need help with this program
BlitzMax Forums/BlitzMax Programming/need help with this program
| ||
hey im making a game called textanoid code: 'Set application and Graphics AppTitle="Textanoid2" Graphics 620,475 'Set the handle to the center of images AutoMidHandle True Type TPaddle Field x,y End Type Type TBall Field x,y 'the coordinates Field directionx, directiony 'the velocities of the ball Field xv Field yv End Type Const BLOCKSTRING:String = "XXXXXXXX" Const paddleimage:String = LoadImage("/Users/sanjitsingh/Downloads/Data/post-13646-0-51208800-1427011572.png") Global ballimage = LoadImage("/Users/sanjitsingh/Downloads/Data/ball.png") Const BLOCKROWS = 3 Const BLOCKCOLUMNS = 7 Const BLOCKXGAP = 85 Const BLOCKYGAP = 32 Const BLOCKXORIGIN = 16 Const BLOCKYORIGIN = 8 Global BLOCKHEIGHT = TextHeight(BLOCKSTRING) Global BLOCKWIDTH = TextWidth(BLOCKSTRING) Global PADDLEWIDTH = TextWidth(paddleimage) Global PADDLEHEIGHT = TextHeight(paddleimage) Global BALLWIDTH = TextWidth(ballimage) Global BALLHEIGHT = TextHeight(ballimage) Const X_RANDOM_FACTOR = 2 Const Y_RANDOM_FACTOR = 1 Const STARTX = 300 Const STARTY = 340 'Initialization 'Seed the random Generator SeedRnd MilliSecs() 'Initialize the score Global score = 0 'The number of total block hits Global blockhits = 0 'The level the player is on Global level = 1 'Create an array of blocks Global blocks[BLOCKROWS, BLOCKCOLUMNS] 'Create a new ball Global ball:TBall = New TBall 'Create a new paddle Global player:TPaddle = New TPaddle 'Initialize the new level NewLevel() Function NewLevel() For rows=0 To BLOCKROWS- 1 For cols=0 To BLOCKCOLUMNS - 1 'Set block to existing(1) blocks[rows,cols] = 1 Next Next ResetLevel() End Function Function ResetLevel() ball.x = 320 ball.y = 150 ball.directiony = 4 ball.directionx = Rand(-5,5) 'Make the ball move in a random direction ball.xv = Rand(LEVEL_START_XV_MIN, LEVEL_START_XV_MAX) ball.yv = Rand(LEVEL_START_YV_MIN, LEVEL_START_YV_MAX) player.x = STARTX player.y = STARTY Delay 500 End Function 'Game Loop While Not KeyDown(KEY_ESCAPE) Cls DrawHUD() TestInput() Collide() DrawBlocks() DrawPaddle() DrawBall() CheckBall() Flip Wend Function DrawHUD() DrawText "Level: " + level, 0, 440 'writes the level DrawText "Score: " + score, 0, 450 'writes the score DrawText "Block Hits: " + blockhits, 0, 460 'writes the block hits End Function Function TestInput() 'hit Esc If KeyDown(KEY_ESCAPE) 'quit the game End 'hits left arrow ElseIf KeyDown(KEY_LEFT) 'move paddle left player.x = player.x - 10 'hits right arrow ElseIf KeyDown(KEY_RIGHT) 'move paddle right player.x = player.x + 10 EndIf If KeyHit(KEY_P) 'make screen blank Cls DrawText "Press 'P' to Unpause Game",400,300 Flip 'wait for player to unpause While Not KeyHit(KEY_P) Wend EndIf End Function Function collide() 'If ball hits human player, reflect it away from him and vary its velocity and direction If ImagesCollide(ballimage, ball.x,ball.y,0,player1image,60,player1.y,0) ball.xv = -ball.xv + Rand(-X_RANDOM_FACTOR,X_RANDOM_FACTOR) ball.yv = ball.yv + Rand(-Y_RANDOM_FACTOR,Y_RANDOM_FACTOR) EndIf Function DrawBlocks() x = BLOCKXORIGIN y = BLOCKYORIGIN 'This variable creates a new level if there are no blocks Local moveToNewLevel = 0 'For all the rows For rows = 0 To BLOCKROWS - 1 'reset rows position x = BLOCKXORIGIN For cols = 0 To BLOCKCOLUMNS - 1 'if the block exists, draw it on the screen If (blocks[rows,cols] = 1) Then DrawText BLOCKSTRING, x, y moveToNewLevel = moveToNewLevel + 1 End If 'Move over to the next block x = x + BLOCKXGAP Next 'Move to the next column y = y + BLOCKYGAP Next If moveToNewLevel = 0 level = level + 1 NewLevel() EndIf End Function Function DrawPaddle() 'Draw the paddle DrawText (paddleimage, player.x, player.y) End Function Function DrawBall() 'draw ball DrawImage (ballimage,ball.x, ball.y) End Function Function CheckBall() 'move and draw ball UpdateBall() 'Check and see if ball hit anything CheckBallWithPaddle() CheckBallWithBlocks() CheckBallWithWalls() End Function Function UpdateBall() 'Move the ball to the left or right ball.x = ball.x + ball.directionx 'Move the ball up or down ball.y = ball.y + ball.directiony End Function Function CheckBallWithPaddle() If ball.x >= player.x And ball.x <= player.x + PADDLEWIDTH And ball.y + BALLHEIGHT >= player.y And ball.y + BALLHEIGHT <= player.y + PADDLEHEIGHT ball.directiony = -ball.directiony + Rand(-3,3) EndIf End Function Function CheckBallWithBlocks() 'y is the first row y = BLOCKYORIGIN For rows = 0 To BLOCKROWS - 1 'Reset x to first block of column x = BLOCKXORIGIN 'For every column of blocks For cols = 0 To BLOCKCOLUMNS - 1' 'If it exists If blocks[rows,cols] 'If the ball hit the block, delete the block If ball.x >= x And ball.x <= x + BLOCKWIDTH And ball.y >= y And ball.y <= y + BLOCKHEIGHT blocks[rows,cols] = 0 'Delete block ball.directiony = -ball.directiony + Rand(-2,2) ' Reverse its direction and add randomizer score = score + 75 blockhits = blockhits + 1 'It can't hit mre than one block, so leave function Return EndIf EndIf 'move to next column x = x + BLOCKXGAP Next 'move to next row y = y + BLOCKYGAP Next End Function Function CheckBallWithWalls() 'if ball hits the left wall, reverse its direction and add randomizer If ball.x <= 0 ball.directionx = -ball.directionx + Rand(-2,2) 'if ball hits top wall, reverse its direction and add randomizer ElseIf ball.y <= 0 ball.directiony = -ball.directiony + Rand(-2,2) 'if it hits right wall, reverse its direction and add randomizer ElseIf ball.x >= 640 - BALLWIDTH ball.directionx = -ball.directionx + Rand(-2,2) 'If ball hits lower wall, dock points for missing ball ElseIf ball.y >= 480 score = score - 200 'reset the level ResetLevel() EndIf End Function the main point of this code is for the game to hit the brick but when I use my paddle image it will just go through the paddle. basically when the ball is falling the paddle is supposed to hit the ball back. but when it falls on the paddle it doesnt fall on it it only goes through the paddle and paddle doesnt reflect the ball back to its target. can somebody please help. I just need it to work with my image paddle. thank you so much. |
| ||
This can have some reasons: 1. The coordinates are not correct. As you switched on AUTOMIDIHANDLE the object are not from PLAYER.X to PLAYER.X+PADLLEWIDTH but from PLAYER.X - PADLLEWIDTH/2 to PLAYER.X+PADLLEWIDTH/2 2.The ball is too fast. If the ball speed is higher than the paddles height, it can go trough within one loop. Example: Take this situation: PADDLEHEIGHT=3, PLAYER.Y=100, BALL.DIRECTIONY=4 BALL.Y=101 In this moment the ball is above the paddle. But in the next round it will be at 104. And now it is below, but was never inside the paddle. I say it again: Please use the forum codes to structure your code for us. Your code has some bugs: 1.Your function Function collide() has no End function 2.It is not possible to convert images to strings. And it is not possible to load something into a CONSTANT: Const paddleimage:String = LoadImage("/Users/sanjitsingh/Downloads/Data/post-13646-0-51208800-1427011572.png") better this way: Global PaddleImage:TImage = LoadImage("/Users/sanjitsingh/Downloads/Data/post-13646-0-51208800-1427011572.png") ..... Global PADDLEWIDTH = ImageWidth(Paddleimage) Global PADDLEHEIGHT = ImageHeight(Paddleimage) .... DrawImage (PaddleImage, player.x, player.y) 3. Your type BALL has no field X and no Y. And you have no PLAYER1 If ImagesCollide(ballimage, ball.x,ball.y,0,player1image,60,player1.y,0) I think you mean: If ImagesCollide(ballimage, ball.xv,ball.yv,0,player1image,60,player.y,0) Here is a code without syntax bugs: Explanations: As I have not your images, I need to replace this part with a "special code" to run the game. You can remove this lines and re-activate your line: 'Global PaddleImage:TImage = LoadImage("/Users/sanjitsingh/Downloads/Data/post-13646-0-51208800-1427011572.png") 'Global BallImage = LoadImage("/Users/sanjitsingh/Downloads/Data/ball.png") Global PaddleImage:TImage = CreateImage(50,8) DrawRect 1,1,49,7 GrabImage PaddleImage,0,0 Cls Global BallImage:TImage = CreateImage(10,10) DrawOval 1,1,9,9 GrabImage BallImage,0,0 Cls General advices There are two different sort of bugs: syntax bugs an logic bugs. To prevent syntax bugs, it is better (for a novice) to start the code after each line, instead of coding the whole game, then try to start with dozends of bugs. In this step-by-step starts the program will not run as expected, but it will run. Use the TABs to structure your code. So you will find missing END FUNCTION, etc... I am interested in supporting you and teaching you, but you need to follow some of the advices. Also the others here will join your threads and will help, when you start to write more carefully. Wish you all the best, and that you become a good coder and a long time member of our forum. What has becomes with your problem from two weeks ago? |
| ||
MidMaster thank you so much for your help and kind words. My coding has improved. I am actually using a blitzbasic textbook for the games but as I also use my resources to design a game I also like to make my own versions of my game. I really apreeciate your help. your advice and code makes sense and I still have a lot to learn before I can become a professional coder. But I owe my gratitude to you. I actually know how to create my own player for this game with the const variable. Example: Const BLOCKSTRING:String = "XXXXXXXX" Const PADDLESTRING:String = "--------" Const BALLSTRING:String = "0". but I thought to myself why not explore and use different ideas. I remember you helped me with my game called space invaders and I followed more of your tips. I really want to you and hope if I have anymore questions I can come to you for help anytime. Thanks again. From you I am learning more things that i was not ware of. Thanks again. I owe you one. |
| ||
Hi Sanjit: As is your code does not run, I get back a: MAX IDE - Compile Error - Expecting expression but encountred end-of-file. Also, your code is a little hard to read (at least for me anyways). You might consider the following. the command STRICT placed at the top of your program will ensure that all variables are defined. This is actually a good thing and can cut down on errors later. You might INDENT your code thus: Function NewLevel() For rows=0 To BLOCKROWS- 1 For cols=0 To BLOCKCOLUMNS - 1 blocks[rows,cols] = 1 'Set block to existing(1) Next Next ResetLevel() End Function Where you put the REMARK just to the right of the code, you won't be confused about which remarks go with which commands. Additionally, BlitzMAX is Caps Blind so you can type out everything in lower or uppercase and it won't make a difference. BlitzMAX's IDE is smart and it will UpperCase commands as needed. |
| ||
....but I thought to myself why not explore and use different ideas. That' a good idea, but in this case you should try to "build &run" your game after each new line of code to prevent "Syntax Errors". Press F5 to check the syntax often. When you add a new structure, you should always add it's END command line in the moment of writing its first line. See the example of how the code is growing over some steps: 1. SuperStrict Graphics 800,600 Global A%, B%, C% Repeat Until KeyHit(KEY_ESCAPE) 2. SuperStrict Graphics 800,600 Global A%, B%, C% Repeat If A=4 Endif Until KeyHit(KEY_ESCAPE) 3. SuperStrict Graphics 800,600 Global A%=4, B%, C% Repeat If A=4 For B=0 to 10 Next Print "working" Endif Until KeyHit(KEY_ESCAPE) 4. SuperStrict Graphics 800,600 Global A%, B%, C% Repeat If A=4 For B=0 to 10 C=C+C Next Print "working" + C Endif Until KeyHit(KEY_ESCAPE) 5. SuperStrict Graphics 800,600 Global A%, B%, C% Repeat If A=4 For B=0 to 10 C=C+C Next ' Print C Endif If KeyDown(KEY_1) Print "KEY 1" Else Endif Until KeyHit(KEY_ESCAPE) Function Bla() End Function 6. SuperStrict Graphics 800,600 Global A%, B%, C% Repeat If A=4 For B=0 to 10 C=C+C Next Print C Endif If KeyDown(KEY_1) 'Print "KEY 1" Bla C A=0 Else If KeyDown(KEY_2) Print "KEY 2" C=0 A=4 Else Endif Until KeyHit(KEY_ESCAPE) Function Bla(Value%) DrawText Value,100,100 End Function You can build a game where TEXTs and IMAGEs are combined... no problem. But the syntax does not allow combining text command and image commands in one line, like you did here: Const paddleimage:String = LoadImage("/Users/sanjitsingh/Downloads/Data/post-13646-0-51208800-1427011572.png") Also CONST needs its value already in the code. Not loaded later or coming from a variable: 'allowed: CONST A%=3 CONST B$="ABC" CONST C%=A ' not allowed: Global X%=4 CONST A%=X CONST B$=LoadText("....") CONST C%=A Another Advice: You only can understand what's going wrong in your game, when you "Slow down" the speed. Try This in your main loop: Global Wait%=10 Repeat ' your code... ..... If KeyDown(KEY_S) ' s=slower Wait=50 Else Wait=10 EndIf Delay Wait Flip Until.... |
| ||
If you want some advice on the ball to paddle collision then the simplest way is to create an invisible hitbox around the paddle that extends below the paddle to compensate for the ball moving faster per frame than the height of the paddle, when the ball is inside this hitbox you can then reposition the ball so it appears above the padding on the Y axis. If you update before render then the ball will never appear to go through the paddle. You might want to look up AABB Axis Align Bounding Box to put a box around the ball and paddle https://www.youtube.com/watch?v=ghqD3e37R7E and use that to create hitboxes you can later check are colliding or not. a = y position of paddle b = the invisible hitbox that follows the paddle on the x axis c = the y position of the ball ![]() example; if BallInsidePaddleHitbox() ball.y = paddle.y-ball.height ' position ball above paddle ' then reverse it's velocity endif Above assumes you've create a function called "BallInsidePaddleHitbox()" (this could be checking ig you paddle and ball AABB's are colliding) that returns true if the ball is inside the paddle. You'll need to later add some additional checks to ensure the ball (that is now colliding) on the last frame was above the paddle else you'll have some odd issues with side collisions but don't be concerned with that just yet. |
| ||
If you want some advice on the ball to paddle collision then the simplest way is to create an invisible hitbox around the paddle that extends below the paddle to compensate for the ball moving faster per frame than the height of the paddle, when the ball is inside this hitbox you can then reposition the ball so it appears above the padding on the Y axis. If you update before render then the ball will never appear to go through the paddle. You might want to look up AABB Axis Align Bounding Box to put a box around the ball and paddle https://www.youtube.com/watch?v=ghqD3e37R7E and use that to create hitboxes you can later check are colliding or not. a = y position of paddle b = the invisible hitbox that follows the paddle on the x axis c = the y position of the ball ![]() example; if BallInsidePaddleHitbox() ball.y = paddle.y-ball.height ' position ball above paddle ' then reverse it's velocity endif Above assumes you've create a function called "BallInsidePaddleHitbox()" (this could be checking if your paddle and ball AABB's are colliding) that returns true if the ball is inside the paddle. You'll need to later add some additional checks to ensure the ball (that is now colliding) on the last frame was above the paddle else you'll have some odd issues with side collisions but don't be concerned with that just yet. |