Hey StOrM3,
After reading your original post yesterday, I thought I'd have a go at helping you out so I wrote the following basic concept code today. It's how I understand your game concept works, from the various posts you've made here.
I hadn't seen any of your source code before today so I'm probably doing things differently to you but it contains all the stuff I remember you having trouble with: collisions, smooth control (mouse control may need tweaking), combination hits, etc.
Hope it's of some use. Feel free to ask any questions, if I can help. BTW, seems like you've got a really nice game concept there - keep up the hard work!
After reading your original post yesterday, I thought I'd have a go at helping you out so I wrote the following basic concept code today. It's how I understand your game concept works, from the various posts you've made here.
I hadn't seen any of your source code before today so I'm probably doing things differently to you but it contains all the stuff I remember you having trouble with: collisions, smooth control (mouse control may need tweaking), combination hits, etc.
Hope it's of some use. Feel free to ask any questions, if I can help. BTW, seems like you've got a really nice game concept there - keep up the hard work!
Graphics3D 800,600,32 SetBuffer BackBuffer() WireFrame 0 AntiAlias 0 SeedRnd MilliSecs() Global frame_count% Global fps% Global slowest_fps% Global fps_timeout% Global frame_time% Global slowest_frame% Global frame_start% fps_timer = CreateTimer(60) slowmo% = False wiref% = False cam = CreateCamera() PositionEntity cam,0,1.5,-36 CameraZoom cam,1.5 light = CreateLight() Type gridT Field entity Field ID Field row%, col% End Type Const END_ROW% = 14 Const END_COL% = 20 Const GRID_START_X# = Float(-END_COL) Const GRID_START_Y# = Float(END_ROW) Const KEY_MOVE_FRAMES% = 8 Const SHOOT_SPEED# = 1.0 ; Grid object IDs. Const ID_NEW_PLAYER% = -1 Const ID_SPACE% = 0 Const ID_WALL% = 1 Const ID_RED_BALL% = 2 Const ID_GREEN_BALL% = 3 Const ID_YELLOW_BALL% = 4 Const ID_CYAN_BALL% = 5 Const ID_HORZ_END% = 7 Const ID_VERT_END% = 8 Const ID_SET_RANDOM% = 9 Const CLOCKWISE% = 1 Const ANTICLOCKWISE% = -1 Const TYPE_PLAYER% = 1 Const TYPE_WALL% = 2 Const TYPE_BALL% = 3 Global move_row% = 0 Global move_col% = 1 Global move_dx#, move_dy# Global move_count% Global player_moving% = False Dim grid.gridT(END_ROW,END_COL) create_level() Global player.gridT = New gridT player\entity = CreateSphere() player\ID = ID_NEW_PLAYER position_player(2,10) EntityShininess player\entity,1 EntityType player\entity,TYPE_PLAYER EntityRadius player\entity,.9,.9 Collisions TYPE_PLAYER,TYPE_BALL,1,1 Collisions TYPE_PLAYER,TYPE_WALL,1,1 ; --- Main loop --- While Not KeyHit(1) frame_start = MilliSecs() If KeyHit(28) Then slowmo = Not slowmo If KeyHit(14) wiref = Not wiref WireFrame wiref EndIf control_player() update_player() UpdateWorld RenderWorld frame_time = MilliSecs() - frame_start show_info() WaitTimer(fps_timer) Flip(1) If slowmo Then Delay 500 Wend ClearWorld End ; Initial level grid layout info. .grid_data Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,1 Data 1,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,1 Data 1,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,1 Data 1,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; ; Player control handler. ; Function control_player() If Not player_moving mxs = MouseXSpeed() MoveMouse 400,300 If mxs frames = Abs(mxs/3) If frames > 10 Then frames = 10 frames = 11 - frames move_player(Sgn(mxs),frames) Else If KeyHit(57) Or MouseHit(1) shoot_player() Else If KeyDown(203) Then move_player(-1,KEY_MOVE_FRAMES) If KeyDown(205) Then move_player(1,KEY_MOVE_FRAMES) EndIf EndIf EndIf End Function ; ; Updates player's movement and handles collisions. ; Function update_player() If player_moving ent = EntityCollided(player\entity,TYPE_BALL) If ent ; A ball was hit... ball.gridT = Object.gridT(EntityName(ent)) If player\ID <> ball\ID player_is_ball(ball\ID) reset_player() position_player(player\row,player\col) Else remove_connected(ball) reset_player() position_player(player\row,player\col) EndIf Else ent = EntityCollided(player\entity,TYPE_WALL) If ent ; A wall was hit... reset_player() position_player(player\row,player\col) Else ; Player moving clockwise/anti-clockwise... TranslateEntity player\entity,move_dx,move_dy,0 move_count = move_count - 1 If Not move_count Then reset_player() EndIf EndIf EndIf End Function ; ; Recusively removes all connected balls of the same type. ; Function remove_connected(ball.gridT) row = ball\row col = ball\col ID = ball\ID HideEntity ball\entity ball\ID = ID_SPACE If grid(row,col-1)\ID = ID Then remove_connected(grid(row,col-1)) If grid(row,col+1)\ID = ID Then remove_connected(grid(row,col+1)) If grid(row-1,col)\ID = ID Then remove_connected(grid(row-1,col)) If grid(row+1,col)\ID = ID Then remove_connected(grid(row+1,col)) End Function ; ; Turns player into a ball of type ID. ; Function player_is_ball(ID) Select ID Case ID_RED_BALL EntityColor player\entity,155,0,0 Case ID_GREEN_BALL EntityColor player\entity,0,155,0 Case ID_YELLOW_BALL EntityColor player\entity,155,155,0 Case ID_CYAN_BALL EntityColor player\entity,0,155,155 End Select player\ID = ID End Function ; ; Resets player's status ready for a new movement. ; Function reset_player() player_moving = False ; Flush all input accumulated while moving. MouseXSpeed() FlushMouse FlushKeys End Function ; ; Moves player around ball grid. ; dir - 1=clockwise, -1=anti-clockwise ; frames - Number of animation frames to make the move. ; Function move_player(dir%, frames%) mr = move_row * Sgn(dir) ; Sgn() ensures dir is either CLOCKWISE mc = move_col * Sgn(dir) ; or ANTICLOCKWISE. new_row = player\row + mr new_col = player\col + mc If dir = CLOCKWISE Select grid(new_row,new_col)\ID Case ID_HORZ_END move_row = mc : move_col = 0 new_row = player\row + (move_row*2) new_col = player\col + (mc*2) Case ID_VERT_END move_col = -mr : move_row = 0 new_row = player\row + (mr*2) new_col = player\col + (move_col*2) End Select Else Select grid(new_row,new_col)\ID Case ID_HORZ_END move_row = mc : move_col = 0 new_row = player\row + (move_row*-2) new_col = player\col + (mc*2) Case ID_VERT_END move_col = -mr : move_row = 0 new_row = player\row + (mr*2) new_col = player\col + (move_col*-2) End Select EndIf player\row = new_row player\col = new_col ; Calculate movement animation to get from old position to new one. start_x# = EntityX(player\entity) start_y# = EntityY(player\entity) end_x# = GRID_START_X + (new_col*2) end_y# = GRID_START_Y - (new_row*2) move_dx# = (end_x - start_x) / frames move_dy# = (end_y - start_y) / frames move_count = frames player_moving = True End Function ; ; Set up player to shoot forward. ; Function shoot_player() If player\row = 2 move_dx = 0 : move_dy = -SHOOT_SPEED ElseIf player\row = END_ROW-2 move_dx = 0 : move_dy = SHOOT_SPEED ElseIf player\col = 2 move_dx = SHOOT_SPEED : move_dy = 0 ElseIf player\col = END_COL-2 move_dx = -SHOOT_SPEED : move_dy = 0 EndIf player_moving = True move_count = 9999 ; Make sure we can reach a wall! End Function ; ; Positions player onscreen at level grid row,col. ; Function position_player(row%, col%) player\row = row player\col = col PositionEntity player\entity,GRID_START_X+(col*2),GRID_START_Y-(row*2),0 ResetEntity player\entity End Function ; ; Create all level objects. ; Function create_level() pos_x# = GRID_START_X pos_y# = GRID_START_Y Restore grid_data For row = 0 To END_ROW For col = 0 To END_COL this.gridT = New gridT this\row = row this\col = col Read datum Select datum Case ID_WALL ent = CreateCube() ScaleMesh ent,1,1,Rnd(1,3) ; For a more interesting looking wall EntityColor ent,0,0,Rand(100,255) ; PositionEntity ent,pos_x,pos_y,0 EntityType ent,TYPE_WALL EntityRadius ent,1,1 NameEntity ent,Handle(this) this\entity = ent this\ID = ID_WALL Case ID_SET_RANDOM ent = CreateSphere() EntityShininess ent,1 PositionEntity ent,pos_x,pos_y,0 EntityType ent,TYPE_BALL EntityRadius ent,1,1 NameEntity ent,Handle(this) this\entity = ent random_ball = Rand(ID_RED_BALL,ID_CYAN_BALL) Select random_ball Case ID_RED_BALL EntityColor ent,155,0,0 Case ID_GREEN_BALL EntityColor ent,0,155,0 Case ID_YELLOW_BALL EntityColor ent,155,155,0 Case ID_CYAN_BALL EntityColor ent,0,155,155 End Select this\ID = random_ball Default this\ID = datum End Select grid(row,col) = this pos_x = pos_x + 2.0 Next pos_x = GRID_START_X pos_y = pos_y - 2.0 Next End Function ; ; Display debug info ; Function show_info() If fps_timeout frame_count = frame_count + 1 If MilliSecs() > fps_timeout Then fps_timeout = MilliSecs() + 1000 fps = frame_count frame_count = 0 If fps < slowest_fps Or slowest_fps = 0 Then slowest_fps = fps EndIf If frame_time > slowest_frame Then slowest_frame = frame_time Color 0,255,0 Text 10,10," Triangles: " + TrisRendered() Color 255,255,0 Text 10,25," Millisecs: " + frame_time Text 10,40," Slowest: " + slowest_frame Color 0,255,255 Text 10,55," FPS: " + fps Text 10,70," Worst: " + slowest_fps Color 255,255,255 Text 200,10,"Move mouse right or press right arrow key to move clockwise" Text 200,25,"Move mouse left or press left arrow key to move anti-clockwise" Text 200,40,"Click left mouse button or press SPACE to shoot" Else ; First call initialization. fps_timeout = MilliSecs() + 1000 EndIf End Function