Hendrik Posted October 17, 2017 Share Posted October 17, 2017 Hey there, i am new to JS and PIXI and tried to rebuild a pong game in PIXI.JS to make it responsive. (https://robots.thoughtbot.com/pong-clone-in-javascript) It seems to work but i run into the issue that all elements have a trail on movement, do i have to rerender the stage to avoid the trail or am i missing something? https://jsfiddle.net/02utycqq/ // define gamne variables const appWidth = window.innerWidth; const appHeight = window.innerHeight; const paddleWidth = 50; const paddleHeight = 10; const ballSize = 5; const appWidthHalf = appWidth / 2; const appHeightHalf = appHeight / 2; const paddleWidthHalf = paddleWidth / 2; const pongColor = 0x57dfbf; const computerPositionX = appWidthHalf - paddleWidthHalf; const computerPositionY = 50; const playerPositionX = computerPositionX; const playerPositionY = appHeight - computerPositionY - paddleHeight; const ballPositionX = appWidthHalf; const ballPositionY = appHeightHalf; const playerSpeed = 4; const computerSpeed = 4; const ballSpeed = 3; // Setup the ticker and the root stage PIXI.Container. const app = new PIXI.Application(appWidth, appHeight, { antialias: false, transparent: false, resolution: 1, }); function Paddle(x, y, width, height) { this.x = x; this.y = y; this.width = width; this.height = height; this.x_speed = 0; this.y_speed = 0; } Paddle.prototype.render = function renderPaddle() { this.graphics = new PIXI.Graphics(); this.graphics.beginFill(pongColor); this.graphics.drawRect(this.x, this.y, this.width, this.height); this.graphics.endFill(); app.stage.addChild(this.graphics); }; Paddle.prototype.move = function (x, y) { this.x += x; this.y += y; this.x_speed = x; this.y_speed = y; if (this.x < 0) { this.x = 0; this.x_speed = 0; } else if (this.x + this.width > appWidth) { this.x = appWidth - this.width; this.x_speed = 0; } }; function Player() { this.paddle = new Paddle(playerPositionX, playerPositionY, paddleWidth, paddleHeight); } Player.prototype.render = function renderPlayer() { this.paddle.render(); }; Player.prototype.update = function () { for (const key in keysDown) { const value = Number(key); if (value === 37) { this.paddle.move(-playerSpeed, 0); } else if (value === 39) { this.paddle.move(playerSpeed, 0); } else { this.paddle.move(0, 0); } } }; function Computer() { this.paddle = new Paddle(computerPositionX, computerPositionY, paddleWidth, paddleHeight); } Computer.prototype.render = function renderComputer() { this.paddle.render(); }; Computer.prototype.update = function (ball) { const x_pos = ball.x; // eslint-disable-next-line let diff = -(this.paddle.x + this.paddle.width / 2 - x_pos); if (diff < 0 && diff < -computerSpeed) { diff = -ballSize; } else if (diff > 0 && diff > computerSpeed) { diff = ballSize; } this.paddle.move(diff, 0); if (this.paddle.x < 0) { this.paddle.x = 0; } else if (this.paddle.x + this.paddle.width > appWidth) { this.paddle.x = appWidth - this.paddle.width; } }; function Ball(x, y) { this.x = x; this.y = y; this.width = ballSize; this.height = ballSize; this.x_speed = 0; this.y_speed = ballSpeed; } Ball.prototype.render = function renderBall() { this.graphics = new PIXI.Graphics(); this.graphics.beginFill(pongColor); this.graphics.drawRect(this.x, this.y, this.width, this.height); this.graphics.endFill(); app.stage.addChild(this.graphics); }; Ball.prototype.update = function (paddle1, paddle2) { this.x += this.x_speed; this.y += this.y_speed; const top_x = this.x - ballSize; const top_y = this.y - ballSize; const bottom_x = this.x + ballSize; const bottom_y = this.y + ballSize; if (this.x - ballSize < 0) { this.x = ballSize; this.x_speed = -this.x_speed; } else if (this.x + ballSize > appWidth) { this.x = appWidth - ballSize; this.x_speed = -this.x_speed; } if (this.y < 0 || this.y > appHeight) { this.x_speed = 0; this.y_speed = ballSpeed; this.x = appWidthHalf; this.y = appHeightHalf; } if (top_y > appHeightHalf) { if ( top_y < paddle1.y + paddle1.height && bottom_y > paddle1.y && top_x < paddle1.x + paddle1.width && bottom_x > paddle1.x ) { this.y_speed = -ballSpeed; this.x_speed += paddle1.x_speed / 2; this.y += this.y_speed; } } else if ( top_y < paddle2.y + paddle2.height && bottom_y > paddle2.y && top_x < paddle2.x + paddle2.width && bottom_x > paddle2.x ) { this.y_speed = ballSpeed; this.x_speed += paddle2.x_speed / 2; this.y += this.y_speed; } }; const player = new Player(); const computer = new Computer(); const ball = new Ball(ballPositionX, ballPositionY); function render() { player.render(); computer.render(); ball.render(); } function update() { player.update(); computer.update(ball); ball.update(player.paddle, computer.paddle); } function step() { update(); render(); // app.ticker.update(step); } document.body.appendChild(app.view); app.ticker.add(step); // Controls const keysDown = {}; window.addEventListener('keydown', (event) => { keysDown[event.keyCode] = true; }); window.addEventListener('keyup', (event) => { delete keysDown[event.keyCode]; }); // resize function for app function resize() { app.view.style.position = 'absolute'; app.view.style.width = `${window.innerWidth}px`; app.view.style.height = `${window.innerHeight}px`; app.view.style.display = 'block'; } window.onresize = () => { app.ticker.add(resize); }; Thanks a lot. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted October 17, 2017 Share Posted October 17, 2017 Ball.prototype.render = function renderBall() { this.graphics = new PIXI.Graphics(); this.graphics.beginFill(pongColor); this.graphics.drawRect(this.x, this.y, this.width, this.height); this.graphics.endFill(); app.stage.addChild(this.graphics); }; So, every time you want to render the ball, you add one more graphics object to the stage tree. You should create that graphics only one time, with fixed x,y=0 or (-width/2, -height/2), then change that graphics position. Quote Link to comment Share on other sites More sharing options...
Hendrik Posted October 17, 2017 Author Share Posted October 17, 2017 5 minutes ago, ivan.popelyshev said: Ball.prototype.render = function renderBall() { this.graphics = new PIXI.Graphics(); this.graphics.beginFill(pongColor); this.graphics.drawRect(this.x, this.y, this.width, this.height); this.graphics.endFill(); app.stage.addChild(this.graphics); }; So, every time you want to render the ball, you add one more graphics object to the stage tree. You should create that graphics only one time, with fixed x,y=0 or (-width/2, -height/2), then change that graphics position. So i should add an update function for each element that just updates the current position, instead of adding multiple instances...i will give it a try. thanks @ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Hendrik Posted October 17, 2017 Author Share Posted October 17, 2017 I decided to rewrite everything ..and managed to get the player movement without the trailing, unfortunately i can't manage to get the ball moving, and i am a bit lost https://jsfiddle.net/hendrikeng/02utycqq/2/ import 'pixi.js'; /* eslint-disable no-undef, func-names, guard-for-in */ /* eslint-disable camelcase,no-restricted-syntax, no-mixed-operators */ // define gamne variables const appWidth = window.innerWidth; const appHeight = window.innerHeight; const paddleWidth = 150; const paddleHeight = 30; const ballSize = 15; const halfBall = ballSize / 2; const appWidthHalf = appWidth / 2; const appHeightHalf = appHeight / 2; const paddleWidthHalf = paddleWidth / 2; const pongColor = 0x57dfbf; const bgColor = 0x282625; const computerPositionX = appWidthHalf - paddleWidthHalf; const computerPositionY = 50; const playerPositionX = computerPositionX; const playerPositionY = appHeight - computerPositionY - paddleHeight; const ballPositionX = appWidthHalf - halfBall; const ballPositionY = appHeightHalf - halfBall; const playerSpeed = 4; const computerSpeed = 4; const ballSpeed = 3; // Setup the ticker and the root stage PIXI.Container. const app = new PIXI.Application(appWidth, appHeight, { antialias: false, backgroundColor: bgColor, transparent: false, resolution: 1, }); // append app to body document.body.appendChild(app.view); // create graphic elements const player = new PIXI.Graphics(); const computer = new PIXI.Graphics(); const ball = new PIXI.Graphics(); // Player player .beginFill(pongColor) .drawRect(playerPositionX, playerPositionY, paddleWidth, paddleHeight) .endFill(); // Computer computer .beginFill(pongColor) .drawRect(computerPositionX, computerPositionY, paddleWidth, paddleHeight) .endFill(); // Ball ball .beginFill(pongColor) .drawRect(ballPositionX, ballPositionY, ballSize, ballSize) .endFill(); // append childs to app app.stage.addChild(player); app.stage.addChild(computer); app.stage.addChild(ball); // Player Movement player.update = function () { for (const key in keysDown) { const value = Number(key); if (value === 37) { player.move(-playerSpeed, 0); } else if (value === 39) { player.move(playerSpeed, 0); } else { player.move(0, 0); } } }; player.move = function (x, y) { this.x += x; this.y += y; this.x_speed = x; this.y_speed = y; if (this.x < -appWidthHalf + paddleWidthHalf) { this.x = -appWidthHalf + paddleWidthHalf; this.x_speed = 0; } else if (this.x + this.width - paddleWidthHalf > appWidthHalf) { this.x = appWidthHalf - this.width + paddleWidthHalf; this.x_speed = 0; } }; // computer Movement computer.update = function (balla) { const x_pos = balla.x; let diff = -(computer.x + paddleWidthHalf - x_pos); if (diff < 0 && diff < -computerSpeed) { diff = -ballSize; } else if (diff > 0 && diff > computerSpeed) { diff = ballSize; } computer.position.set(diff, 0); if (computer.x < 0) { computer.x = 0; } else if (computer.x + paddleWidthHalf > appWidth) { computer.x = appWidth - paddleWidthHalf; } }; // Ball Movement ball.position.set = function (paddle1, paddle2) { this.x += this.x_speed; this.y += this.y_speed; const top_x = this.x - ballSize; const top_y = this.y - ballSize; const bottom_x = this.x + ballSize; const bottom_y = this.y + ballSize; if (this.x - ballSize < 0) { this.x = ballSize; this.x_speed = -this.x_speed; } else if (this.x + ballSize > appWidth) { this.x = appWidth - ballSize; this.x_speed = -this.x_speed; } if (this.y < 0 || this.y > appHeight) { this.x_speed = 0; this.y_speed = ballSpeed; this.x = appWidthHalf; this.y = appHeightHalf; } if (top_y > appHeightHalf) { if ( top_y < paddle1.y + paddle1.height && bottom_y > paddle1.y && top_x < paddle1.x + paddle1.width && bottom_x > paddle1.x ) { this.y_speed = -ballSpeed; this.x_speed += paddle1.x_speed / 2; this.y += this.y_speed; } } else if ( top_y < paddle2.y + paddle2.height && bottom_y > paddle2.y && top_x < paddle2.x + paddle2.width && bottom_x > paddle2.x ) { this.y_speed = ballSpeed; this.x_speed += paddle2.x_speed / 2; this.y += this.y_speed; } }; // controls const keysDown = {}; window.addEventListener('keydown', (event) => { keysDown[event.keyCode] = true; }); window.addEventListener('keyup', (event) => { delete keysDown[event.keyCode]; }); // update function function update() { player.update(); computer.update(ball); ball.position.set(player, computer); } // game loop app.ticker.add(update); Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted October 17, 2017 Share Posted October 17, 2017 you cant just override setter of position "ball.position.set". It just strange, however it might work, I dont see problems in your code. I suggest you to debug it and then if it doesnt work for you, ask in "coding&design" section, because I think you have more problems with javascript than with pixi. Please read that book: http://shop.oreilly.com/product/9780596805531.do Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted October 17, 2017 Share Posted October 17, 2017 I think the problem is that "ball.position.set" function thinks that "ball.position" is "this", and you want to work with "ball" as this. Dont put that function in "position". Quote Link to comment Share on other sites More sharing options...
Hendrik Posted October 17, 2017 Author Share Posted October 17, 2017 thanks a lot @ivan.popelyshev much appreciated Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.