最近,我已经开始制作乒乓球游戏,因为我关注的教程告诉我我现在可以制作简单的游戏。
我猜Pong并不像我想象的那样简单。
首先,这是代码:
#include "MainWindow.h"
#include "Game.h"
#include <ctime>
#include <iostream>
#include <cstdlib>
using namespace std;
Game::Game(MainWindow& wnd)
:
wnd(wnd),
gfx(wnd)
{
}
void Game::Go()
{
gfx.BeginFrame();
UpdateModel();
ComposeFrame();
gfx.EndFrame();
}
void Game::UpdateModel()
{
///Moves player paddles
MovePaddle();
///Checks if player paddles are inside the given parameters.
LeftPlayerY = WallInsideBorder(LeftPlayerY);
RightPlayerY = WallInsideBorder(RightPlayerY);
PongBallPhysics();
IsGoal();
}
void Game::ComposeFrame()
{
DrawBall(BallX, BallY, BallRed, BallGreen, BallBlue);
DrawWall(LeftPlayerX, LeftPlayerY);
DrawWall(RightPlayerX, RightPlayerY);
DrawThePixelatedWall();
DrawScoreboard();
}
///Draws the Pongball
void Game::DrawBall(int BallX, int BallY, int BallRed, int BallGreen, int BallBlue)
{
///Middle layer of pixels
gfx.PutPixel(BallX, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 2, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 3, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 1, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 2, BallY, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 3, BallY, BallRed, BallGreen, BallBlue);
///Layer of Pixels above middle layer
gfx.PutPixel(BallX - 3, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 2, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 1, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 2, BallY - 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 3, BallY - 1, BallRed, BallGreen, BallBlue);
///Layer of Pixels beneath top layer
gfx.PutPixel(BallX - 2, BallY - 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 1, BallY - 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY - 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY - 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 2, BallY - 2, BallRed, BallGreen, BallBlue);
///Top Layer
gfx.PutPixel(BallX - 1, BallY - 3, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY - 3, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY - 3, BallRed, BallGreen, BallBlue);
///Layer beneath middle layer
gfx.PutPixel(BallX - 3, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 2, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 1, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 2, BallY + 1, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 3, BallY + 1, BallRed, BallGreen, BallBlue);
///Layer above bottom layer
gfx.PutPixel(BallX - 2, BallY + 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX - 1, BallY + 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY + 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY + 2, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 2, BallY + 2, BallRed, BallGreen, BallBlue);
///Bottom layer
gfx.PutPixel(BallX - 1, BallY + 3, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX, BallY + 3, BallRed, BallGreen, BallBlue);
gfx.PutPixel(BallX + 1, BallY + 3, BallRed, BallGreen, BallBlue);
}
///Draws the walls for the players (100 pixels tall)
void Game::DrawWall(int XCoordinate, int YCoordinate)
{
if (XCoordinate == LeftPlayerX)
{
for (int i = -50; i <= 50; ++i)
{
gfx.PutPixel(XCoordinate, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate - 1, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate - 2, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate - 3, YCoordinate + i, 255, 255, 255);
}
}
if (XCoordinate == RightPlayerX)
{
for (int i = -50; i <= 50; ++i)
{
gfx.PutPixel(XCoordinate, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate + 1, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate + 2, YCoordinate + i, 255, 255, 255);
gfx.PutPixel(XCoordinate + 3, YCoordinate + i, 255, 255, 255);
}
}
}
///Draws the boundary between the player fields
void Game::DrawThePixelatedWall()
{
for (int i = 0; i <= 597; i = i + 3)
{
gfx.PutPixel(399, i, 255, 255, 255);
}
}
///Draws the scoreboard.
void Game::DrawScoreboard()
{
switch (LeftPlayerScore) {
case 0:
for (int i = 6; i <= 50; ++i)
{
gfx.PutPixel(320 + 6, i, 255, 255, 255);
gfx.PutPixel(320 + 5, i, 255, 255, 255);
gfx.PutPixel(320 - 5, i, 255, 255, 255);
gfx.PutPixel(320 - 6, i, 255, 255, 255);
gfx.PutPixel(320 + 7, i, 255, 255, 255);
gfx.PutPixel(320 - 7, i, 255, 255, 255);
}
for (int i = -4; i <= 6; ++i)
{
gfx.PutPixel(320 + i, 6, 255, 255, 255);
gfx.PutPixel(320 + i, 7, 255, 255, 255);
gfx.PutPixel(320 + i, 8, 255, 255, 255);
gfx.PutPixel(320 + i, 50, 255, 255, 255);
gfx.PutPixel(320 + i, 49, 255, 255, 255);
gfx.PutPixel(320 + i, 48, 255, 255, 255);
}
break;
case 1:
for (int i = 6; i <= 50; ++i)
{
gfx.PutPixel(320, i, 255, 255, 255);
gfx.PutPixel(320 + 1, i, 255, 255, 255);
gfx.PutPixel(320 - 1, i, 255, 255, 255);
}
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
for (int i = 6; i <= 50; ++i)
{
gfx.PutPixel(320 + 6, i, 255, 255, 255);
gfx.PutPixel(320 + 5, i, 255, 255, 255);
gfx.PutPixel(320 - 5, i, 255, 255, 255);
gfx.PutPixel(320 - 6, i, 255, 255, 255);
gfx.PutPixel(320 + 7, i, 255, 255, 255);
gfx.PutPixel(320 - 7, i, 255, 255, 255);
}
for (int i = -4; i <= 6; ++i)
{
gfx.PutPixel(320 + i, 6, 255, 255, 255);
gfx.PutPixel(320 + i, 7, 255, 255, 255);
gfx.PutPixel(320 + i, 8, 255, 255, 255);
gfx.PutPixel(320 + i, 50, 255, 255, 255);
gfx.PutPixel(320 + i, 49, 255, 255, 255);
gfx.PutPixel(320 + i, 48, 255, 255, 255);
gfx.PutPixel(320 + i, 27, 255, 255, 255);
gfx.PutPixel(320 + i, 28, 255, 255, 255);
}
break;
case 9:
break;
case 10:
break;
}
switch (RightPlayerScore) {
case 0:
for (int i = 6; i <= 50; ++i)
{
gfx.PutPixel(478 + 6, i, 255, 255, 255);
gfx.PutPixel(478 + 5, i, 255, 255, 255);
gfx.PutPixel(478 - 5, i, 255, 255, 255);
gfx.PutPixel(478 - 6, i, 255, 255, 255);
gfx.PutPixel(478 + 7, i, 255, 255, 255);
gfx.PutPixel(478 - 7, i, 255, 255, 255);
}
for (int i = -4; i <= 6; ++i)
{
gfx.PutPixel(478 + i, 6, 255, 255, 255);
gfx.PutPixel(478 + i, 7, 255, 255, 255);
gfx.PutPixel(478 + i, 8, 255, 255, 255);
gfx.PutPixel(478 + i, 50, 255, 255, 255);
gfx.PutPixel(478 + i, 49, 255, 255, 255);
gfx.PutPixel(478 + i, 48, 255, 255, 255);
}
break;
case 1:
for (int i = 6; i <= 50; ++i)
{
gfx.PutPixel(478, i, 255, 255, 255);
gfx.PutPixel(478 + 1, i, 255, 255, 255);
gfx.PutPixel(478 - 1, i, 255, 255, 255);
}
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
}
}
///Checks if Walls are inside
int Game::WallInsideBorder(int YCoordinate)
{
if (YCoordinate + 50 >= gfx.ScreenHeight)
{
return gfx.ScreenHeight - 51;
}
if (YCoordinate - 50 < 0)
{
return 51;
}
return YCoordinate;
}
///Pong Ball physics :D
void Game::PongBallPhysics()
{
BallX = BallX + BallVX;
BallY = BallY + BallVY;
///Sets initial VX and VY
if (FirstTime)
{
srand(time(NULL));
BallY = rand() % 599;
BallVX = rand() % 4 + 1;
srand(time(NULL));
BallVY = rand() % 4 + 1;
FirstTime = false;
}
/// Touching top or bottom?
if (BallY - 3 < 0)
{
DoBounceCalculation();
BallY = 3;
}
if (BallY + 3 > 599)
{
DoBounceCalculation();
BallY = 595;
}
///Touching a wall?
/// ERROR, BallVX goes PAST LeftPlayerX/RightPlayerX!
IsTouchingWall();
}
///Makes the angle be the same as when it hit the wall/boundary.Looked at and is working
void Game::DoBounceCalculation()
{
BallVY = -BallVY;
}
///Swaps two variables, looked at and should be working
void Game::Swap(int &x, int &y)
{
int SwapVariable = x;
x = y;
y = SwapVariable;
}
///Checks if ball is in opponent's goal, looked at and is working
void Game::IsGoal()
{
if (BallX - 3 <= 0)
{
RightPlayerScore++;
BallX = 399;
FirstTime = true;
}
if (BallX + 3 >= gfx.ScreenWidth)
{
LeftPlayerScore++;
BallX = 399;
FirstTime = true;
}
}
///Moves player walls, looked at and is working
void Game::MovePaddle()
{
if (wnd.kbd.KeyIsPressed(0x57))
{
LeftPlayerY = LeftPlayerY - 3;
}
if (wnd.kbd.KeyIsPressed(0x53))
{
LeftPlayerY = LeftPlayerY + 3;
}
if (wnd.kbd.KeyIsPressed(0x49))
{
RightPlayerY = RightPlayerY - 3;
}
if (wnd.kbd.KeyIsPressed(0x4B))
{
RightPlayerY = RightPlayerY + 3;
}
}
///Checks if Ball is touching Player paddles and changes velocity accordingly, this is bwoke man, check it
void Game::IsTouchingWall()
{
// if-statement that checks if the ball is gonna hit the paddle in the next frame.
// The problem is, that VX or VY skip the pixels between (when they're set to anything higher than 1)
// So that they jump other the paddle.
}
,如果您有兴趣,这是标题文件。
#pragma once
#include "Keyboard.h"
#include "Mouse.h"
#include "Graphics.h"
class Game
{
public:
Game(class MainWindow& wnd);
Game(const Game&) = delete;
Game& operator=(const Game&) = delete;
void Go();
private:
void ComposeFrame();
void UpdateModel();
/********************************/
/* User Functions */
void DrawBall(int BallX, int BallY, int BallRed, int BallGreen, int BallBlue);
void DrawWall(int XCoordinate, int YCoordinate);
void DrawThePixelatedWall();
void DrawScoreboard();
int WallInsideBorder(int YCoordinate);
void PongBallPhysics();
void DoBounceCalculation();
void Swap(int& x, int& y);
void IsGoal();
void MovePaddle();
void IsTouchingWall();
/********************************/
private:
MainWindow& wnd;
Graphics gfx;
/********************************/
/* User Variables */
int BallVX = 0;
int BallVY = 0;
int BallX = 399;
int BallY = 0;
int BallRed = 255;
int BallGreen = 255;
int BallBlue = 255;
const int LeftPlayerX = 100;
int LeftPlayerY = 299;
const int RightPlayerX = 700;
int RightPlayerY = 299;
int LeftPlayerScore = 0;
int RightPlayerScore = 0;
bool FirstTime = true;
/********************************/
};
如果您不熟悉Pong游戏,请单击此处。基本上,在乒乓球比赛中,您尝试使乒乓球越过球员桨,需要捍卫自己的领域。您可以通过以乒乓球方式移动桨来"捍卫",从而将其朝对手朝随机方向发射。
我现在面临的问题是,我无法使Pongball的Hitbox击中播放器的Hitbox。这是因为乒乓球通过将"加速器"添加到坐标中来移动。
ballx = ballx ballvx; bally = bally ballvy;
这意味着它可以跳过桨的刺激箱,而不是与桨碰撞。无论如何,这种方法是错误的,因为通过加速到不同的方向来改变乒乓球的方向,也使乒乓球更快。
我应该补充说gfx.putpixel()函数是由教程给我的,它的工作原理:gfx.putpixel(xCoortion,ycoorcord,ycoorcord,ycoorcord,ycoordication,ycoorcord,red value,green value,blue value);,据我所知,绘制功能并没有引起任何问题,因此您可能应该跳过它们。
我对你们的问题是:我应该如何检测到乒乓球会与桨碰相撞?
游戏中的碰撞检测并不是一项琐碎的任务。但是对于乒乓球中最简单的情况,您可以无视桨和球的大小,足以与桨相交球轨迹。换句话说,您可以采用两个线段:首先从上帧的球位置到当前的球位置,第二个从桨的一端到另一端,然后在球上弹跳。
。