(01-25-2024, 08:59 PM)aliensoldier Wrote: I have updated the code of the ball and the player cpu, in the ball we have get_player_cpu(), and in the cpu we have get_ball(). With this I have recreated the error that I get with a more complete code
I have to make it short, because I gotta go to bed
player.n7, ball.n7 and player-cpu.n7 is not where you should implement get_player, get_ball and get_player_cpu. Nor should you in these file store any objects that are used in the game. For example, player.n7 should only look like this:
Code:
'player
function Player()
player = []
player.Width = 20
player.Height = 100
player.x = 32 - player.Width/2
player.y = 240 - player.Height/2
player.speed = 5
player.live = true
player.update = function()
if this.live = true
this.move()
endif
endfunc
player.Draw = function()
if this.live = true
set color 255,0,205
draw rect this.x,this.y,this.Width,this.Height,true
endif
endfunc
player.move = function()
if keydown(KEY_UP,false) and this.y > 16
this.y = this.y - this.speed
elseif keydown(KEY_DOWN,false) and this.y < 370
this.y = this.y + this.speed
endif
endfunc
return player
endfunc
ball.n7 should look like this:
Code:
'ball
include "player.n7"
include "miscellaneous.n7"
' Marcus, use the getter when needed instead. ball.n7 should just be the implementation for a ball.
'visible player = get_player()
function Ball()
ball = []
ball.Width = 16
ball.Height = 16
ball.x = 320 - ball.Width / 2
ball.y = 240 - ball.Height / 2
ball.speedX = 2
ball.speedY = 2
ball.live = true
ball.update = function()
if this.live = true
this.move()
this.bounce()
this.collision_player()
endif
endfunc
ball.Draw = function()
if this.live = true
set color 200,200,200
draw rect this.x,this.y,this.Width,this.Height,true
'draw ellipse this.x,this.y,9,9,true
endif
endfunc
ball.move = function()
this.x = this.x + this.speedX
this.y = this.y + this.speedY
endfunc
ball.bounce = function()
if this.x <= 0 or this.x >= 640
this.speedX = this.speedX * -1
endif
if this.y <= 0 or this.y >= 480
this.speedY = this.speedY * -1
endif
endfunc
ball.collision_player = function()
'colision con la x
'if collision_rect(this.x+this.speedX,this.y,this.Width,this.Height,player.x,player.y,player.Width,player.Height)
' this.speedX = this.speedX * -1
'endif
'colision con la y
'if collision_rect(this.x,this.y+this.speedY,this.Width,this.Height,player.x,player.y,player.Width,player.Height)
' this.speedY = this.speedY * -1
'endif
' Marcus.
player = get_player()
' Check if they overlap.
if collision_rect(this.x,this.y,this.Width,this.Height,player.x,player.y,player.Width,player.Height)
' Calculate delta x and delta y, between the center of the ball and the center of the
' paddle. Divide the delta x value width the width of the paddle and delta y with the
' height of the paddle to normalize them (make comparison valid).
dx = (this.x + this.Width/2 - (player.x + player.Width/2))/player.Width
dy = (this.y + this.Height/2 - (player.y + player.Height/2))/player.Height
' If dx is higher, it means that there's less overlapping along the x-axis. In that
' case bounce left or right.
if |dx| >= |dy|
' dx < 0, ball should bounce to the left, and we also move the ball to the left so
' that there's no longer any collision.
if dx < 0
this.speedX = -|this.speedX|
this.x = player.x - this.Width
' dx > 0, ball should bounce to the right, and move the ball to the right of the
' paddle.
else
this.speedX = |this.speedX|
this.x = player.x + player.Width
endif
' dy is higher, same principle as for dx :)
else
if dy < 0
this.speedY = -|this.speedY|
this.y = player.y - this.Height
else
this.speedY = |this.speedY|
this.y = player.y + player.Height
endif
endif
endif
endfunc
return ball
endfunc
It is in pong.n7 that you call Player(), Ball() etc to create the actual game objects. Therefor it is in pong.n7 that you should implement get_player, get_ball and get_player_cpu, because it is pong.n7 that owns and manages these objects.
Code:
'pong
include "player.n7"
include "player-cpu.n7"
include "ball.n7"
' Marcus, objects and getters. This file is the owner of the sprites, so this is where the getters
' belong.
visible player, player_cpu, ball
function get_player(); return player; endfunc
function get_player_cpu(); return player_cpu; endfunc
function get_ball(); return ball; endfunc
set window "example pong",640,480,false
set redraw off
'objeto-----------------------------------
player = Player()
player_cpu = Player_Cpu()
ball = Ball()
while not keydown(KEY_ESCAPE,true)
set color 0,0,0
cls
'objetos-----------------------------
player.update()
player.Draw()
player_cpu.update()
player_cpu.Draw()
ball.update()
ball.Draw()
'lineas para el fondo------------------
'draw rect 320,32,2,60,true
'draw rect 320,120,2,60,true
'draw rect 320,210,2,60,true
'draw rect 320,300,2,60,true
'draw rect 320,390,2,60,true
'draw line 320,32,320,460
'draw line 330,32,330,460
redraw
fwait 60
wend
The error you see should disappear if you do it like this. The problem in your code now is that when this line executes in player-cpu.n7:
Code:
visible ball = get_ball()
the ball hasn't even been created yet. So when you use that visible ball variable in your cpu update function things go very wrong. You shouldn't store the ball as a visible variable in player-cpu.n7 at all. Rather call get_ball() (implemented in pong.n7) in the player cpu update function.
Or why not just pass the ball as a parameter to player.update and player_cpu.update?