贪吃蛇游戏边界碰撞
Snake game border collision
我想知道是否有人可以帮助我编写一些代码。
下面我有一些可控圆圈的代码(代表蛇头)
我可以 modify/add 对下面的代码做些什么,以便当蛇与 border/boundaries 碰撞时,它会从另一侧重复?
我已将游戏分辨率设置为 1024 x 768
非常感谢任何帮助:)
snake.cpp
#include "snake.hpp"
#include <cstdlib>
void Snake::move()
{
switch(direction_){
case Direction::North:
position_.y += 10;
break;
case Direction::East:
position_.x += 10;
break;
case Direction::South:
position_.y -= 10;
break;
case Direction::West:
position_.x -= 10;
}
}
void Snake::render(prg::Canvas& canvas) const
{
canvas.drawCircle(getPosition().x, getPosition().y,20,prg::Colour::WHITE);
}
void Snake::changeDirection(Direction new_direction)
{
direction_ = new_direction;
}
play_state.cpp
#include "play_state.hpp"
#include "ai_snake.hpp"
#include "player_snake.hpp"
#include <iostream>
const size_t MaxShapes {5};
const unsigned int MaxScale {5};
bool PlayState::onCreate()
{
snakes_.push_back(new AISnake);
snakes_.back()->setPosition(Position(100,100));
snakes_.push_back(new PlayerSnake);
snakes_.back()->setPosition(Position(50,50));
double x, y;
for(unsigned shape = 0;shape < MaxShapes;shape++)
{
x = (double)(rand() % prg::application.getScreenWidth());
y = (double)(rand() % prg::application.getScreenHeight());
shapes_.push_back(Square({x, y}));
}
return true;
}
bool PlayState::onDestroy()
{
return true;
}
void PlayState::onEntry()
{
prg::application.addKeyListener(*this);
game_timer_.start();
}
void PlayState::onExit()
{
prg::application.removeKeyListener(*this);
game_timer_.stop();
}
void PlayState::onUpdate()
{
}
void PlayState::onRender(prg::Canvas& canvas)
{
const std::string text = "";
canvas.blitFast(
background_,
canvas.getWidth() / 2 - background_.getWidth() / 2,
canvas.getHeight() / 2 - background_.getHeight() / 2
);
prg::uint text_dims[2];
prg::Font::MASSIVE.computePrintDimensions(text_dims, text);
prg::Font::MASSIVE.print(
canvas,
prg::application.getScreenWidth() / 2 - text_dims[0] / 2,
prg::application.getScreenHeight() / 2 - text_dims[1] / 2,
prg::Colour::RED,
text);
for(const auto snake : snakes_) {
snake->render(canvas);
}
for(Shape shapes : shapes_) {
shapes.render(canvas);
}
}
bool PlayState::onKey(const prg::IKeyEvent::KeyEvent& key_event)
{
if(key_event.key_state == KeyEvent::KB_DOWN) {
switch(key_event.key) {
case KeyEvent::KB_ESC_KEY:
prg::application.exit();
break;
}
}
return true;
}
void PlayState::onTimer(prg::Timer& timer)
{
for(auto snake : snakes_) {
snake->move();
}
}
play_state.hpp
#if !defined PLAY_STATE_HPP
#define PLAY_STATE_HPP
#include <prg_interactive.hpp>
#include "snake.hpp"
#include "square.hpp"
#include <list>
//Example of forward declaration of Snake class
class Snake;
class PlayState final : public prg::IAppState,
public prg::IKeyEvent,
public prg::ITimerEvent {
public:
PlayState() = default;
bool onCreate() override;
bool onDestroy() override;
void onEntry() override;
void onExit() override;
void onUpdate() override;
void onRender(prg::Canvas& canvas) override;
bool onKey(const prg::IKeyEvent::KeyEvent& key_event) override;
void onTimer(prg::Timer& timer) override;
private:
//Snake* snakes_[2] {nullptr,nullptr};
std::list<Snake*> snakes_;
prg::Timer game_timer_ {0, 1000 / 30, *this};
const prg::Image background_ {prg::ImageFile("resources/images/border.bmp").load()};
std::vector<Shape> shapes_;
};
#endif // PLAY_STATE_HPP
这适用于 1024x768 的边界:
if (position_.x < 0) position_.x = 1023; else if (position_.x > 1023) position_.x = 0;
if (position_.y < 0) position_.y = 767; else if (position_.y > 767) position_.y = 0;
注意宽度1024表示X在0和[=之间26=]1023!
从您的代码来看,您使用了 10x10 的块。如果是这种情况,您应该根据需要自定义上面的代码。
编辑:
根据评论和我的回答,我将其合并为您可以遵循的代码:
#include "snake.hpp"
#include <cstdlib>
void Snake::move()
{
switch(direction_){
case Direction::North:
position_.y += 1;
break;
case Direction::East:
position_.x += 1;
break;
case Direction::South:
position_.y -= 1;
break;
case Direction::West:
position_.x -= 1;
}
if (position_.x < 0) position_.x = 63; else if (position_.x > 63) position_.x = 0;
if (position_.y < 0) position_.y = 47; else if (position_.y > 47) position_.y = 0;
}
void Snake::render(prg::Canvas& canvas) const
{
canvas.drawCircle(getPosition().x * 16, getPosition().y * 16,16,prg::Colour::WHITE);
}
void Snake::changeDirection(Direction new_direction)
{
direction_ = new_direction;
}
这是一个 16x16 像素的 64x48 网格,分辨率为 1024x768。
玩得开心!
我想知道是否有人可以帮助我编写一些代码。 下面我有一些可控圆圈的代码(代表蛇头)
我可以 modify/add 对下面的代码做些什么,以便当蛇与 border/boundaries 碰撞时,它会从另一侧重复?
我已将游戏分辨率设置为 1024 x 768
非常感谢任何帮助:)
snake.cpp
#include "snake.hpp"
#include <cstdlib>
void Snake::move()
{
switch(direction_){
case Direction::North:
position_.y += 10;
break;
case Direction::East:
position_.x += 10;
break;
case Direction::South:
position_.y -= 10;
break;
case Direction::West:
position_.x -= 10;
}
}
void Snake::render(prg::Canvas& canvas) const
{
canvas.drawCircle(getPosition().x, getPosition().y,20,prg::Colour::WHITE);
}
void Snake::changeDirection(Direction new_direction)
{
direction_ = new_direction;
}
play_state.cpp
#include "play_state.hpp"
#include "ai_snake.hpp"
#include "player_snake.hpp"
#include <iostream>
const size_t MaxShapes {5};
const unsigned int MaxScale {5};
bool PlayState::onCreate()
{
snakes_.push_back(new AISnake);
snakes_.back()->setPosition(Position(100,100));
snakes_.push_back(new PlayerSnake);
snakes_.back()->setPosition(Position(50,50));
double x, y;
for(unsigned shape = 0;shape < MaxShapes;shape++)
{
x = (double)(rand() % prg::application.getScreenWidth());
y = (double)(rand() % prg::application.getScreenHeight());
shapes_.push_back(Square({x, y}));
}
return true;
}
bool PlayState::onDestroy()
{
return true;
}
void PlayState::onEntry()
{
prg::application.addKeyListener(*this);
game_timer_.start();
}
void PlayState::onExit()
{
prg::application.removeKeyListener(*this);
game_timer_.stop();
}
void PlayState::onUpdate()
{
}
void PlayState::onRender(prg::Canvas& canvas)
{
const std::string text = "";
canvas.blitFast(
background_,
canvas.getWidth() / 2 - background_.getWidth() / 2,
canvas.getHeight() / 2 - background_.getHeight() / 2
);
prg::uint text_dims[2];
prg::Font::MASSIVE.computePrintDimensions(text_dims, text);
prg::Font::MASSIVE.print(
canvas,
prg::application.getScreenWidth() / 2 - text_dims[0] / 2,
prg::application.getScreenHeight() / 2 - text_dims[1] / 2,
prg::Colour::RED,
text);
for(const auto snake : snakes_) {
snake->render(canvas);
}
for(Shape shapes : shapes_) {
shapes.render(canvas);
}
}
bool PlayState::onKey(const prg::IKeyEvent::KeyEvent& key_event)
{
if(key_event.key_state == KeyEvent::KB_DOWN) {
switch(key_event.key) {
case KeyEvent::KB_ESC_KEY:
prg::application.exit();
break;
}
}
return true;
}
void PlayState::onTimer(prg::Timer& timer)
{
for(auto snake : snakes_) {
snake->move();
}
}
play_state.hpp
#if !defined PLAY_STATE_HPP
#define PLAY_STATE_HPP
#include <prg_interactive.hpp>
#include "snake.hpp"
#include "square.hpp"
#include <list>
//Example of forward declaration of Snake class
class Snake;
class PlayState final : public prg::IAppState,
public prg::IKeyEvent,
public prg::ITimerEvent {
public:
PlayState() = default;
bool onCreate() override;
bool onDestroy() override;
void onEntry() override;
void onExit() override;
void onUpdate() override;
void onRender(prg::Canvas& canvas) override;
bool onKey(const prg::IKeyEvent::KeyEvent& key_event) override;
void onTimer(prg::Timer& timer) override;
private:
//Snake* snakes_[2] {nullptr,nullptr};
std::list<Snake*> snakes_;
prg::Timer game_timer_ {0, 1000 / 30, *this};
const prg::Image background_ {prg::ImageFile("resources/images/border.bmp").load()};
std::vector<Shape> shapes_;
};
#endif // PLAY_STATE_HPP
这适用于 1024x768 的边界:
if (position_.x < 0) position_.x = 1023; else if (position_.x > 1023) position_.x = 0;
if (position_.y < 0) position_.y = 767; else if (position_.y > 767) position_.y = 0;
注意宽度1024表示X在0和[=之间26=]1023!
从您的代码来看,您使用了 10x10 的块。如果是这种情况,您应该根据需要自定义上面的代码。
编辑:
根据评论和我的回答,我将其合并为您可以遵循的代码:
#include "snake.hpp"
#include <cstdlib>
void Snake::move()
{
switch(direction_){
case Direction::North:
position_.y += 1;
break;
case Direction::East:
position_.x += 1;
break;
case Direction::South:
position_.y -= 1;
break;
case Direction::West:
position_.x -= 1;
}
if (position_.x < 0) position_.x = 63; else if (position_.x > 63) position_.x = 0;
if (position_.y < 0) position_.y = 47; else if (position_.y > 47) position_.y = 0;
}
void Snake::render(prg::Canvas& canvas) const
{
canvas.drawCircle(getPosition().x * 16, getPosition().y * 16,16,prg::Colour::WHITE);
}
void Snake::changeDirection(Direction new_direction)
{
direction_ = new_direction;
}
这是一个 16x16 像素的 64x48 网格,分辨率为 1024x768。
玩得开心!