#javascript #p5.js
#javascript #p5.js
Вопрос:
Я все еще новичок в этом деле, поэтому не знаю, как создать коллайдер. Моя конечная цель — создать игру, подобную игре Chrome dinosaur. Те же принципы, и все. Однако мой вопрос в том, как мне вообще создать коллайдер. Я буду использовать .gif для «динозавра». Я хотел бы сделать так, чтобы, если этот коллайдер коснется другого коллайдера, игра остановится и будет показано «game over». Я пытался создать коллайдер, но они просто продолжают отображаться под экраном, на котором показана игра. Советы, рекомендации или рекомендации Ant? Спасибо
Код выглядит следующим образом:
let img; //background
var bgImg; //also the background
var x1 = 0;
var x2;
var scrollSpeed = 4; //how fast background is
let music; //for music
let catBus; //catbus
//collider variables
let tinyToto;
let tiniestToto;
let hin;
let totoWithBag;
let noFace;
let happySoot;
var mode; //determines whether the game has started
let gravity = 0.2; //jumping forces
let velocity = 0.1;
let upForce = 7;
let startY = 730; //where cat bus jumps from
let startX = 70;
let totoX = 900;
let totoY = 70;
let tinToX = 900;
let tinToY = 70;
var font1; //custom fonts
var font2;
p5.disableFriendlyErrors = true; //avoids errors
function preload() {
bgImg = loadImage("backgwound.png"); //importing background
music = loadSound("catbus theme song.mp3"); //importing music
font1 = loadFont("Big Font.TTF");
font2 = loadFont("Smaller Font.ttf");
//tinyToto.setCollider("rectangle",0,25,75,75)
}
function setup() {
createCanvas(1000, 1000); //canvas size
img = loadImage("backgwound.png"); //background in
x2 = width;
music.loop(); //loops the music
catBus = {
//coordinates for catbus
x: startX,
y: startY,
};
/*
tinyToto = {
x: totoX,
y: totoY,
}
tinTo = {
x : tinToX,
y: tinToY,
}
*/
catGif = createImg("catgif.gif"); //creates catbus
catGif.position(catBus.x, catBus.y); //creates position
catGif.size(270, 100); //creates how big
/*
tinyToto = createImg("TinyToto.gif")
tinyToto.position(tinyToto.x, tinyToto.y)
tinyToto.size(270,100)
tiniestTo = createImg("tiniest Toto.gif")
tiniestTo.position(tinToX.x, tinToY.y)
tiniestTo.size(270,100)
*/
mode = 0; //game start
textSize(50); //text size
}
function draw() {
let time = frameCount; //start background loop
image(img, 0 - time, 0);
image(bgImg, x1, 2, width, height);
image(bgImg, x2, 2, width, height);
x1 -= scrollSpeed;
x2 -= scrollSpeed;
if (x1 <= -width) {
x1 = width;
}
if (x2 <= -width) {
x2 = width;
} //end background loop
fill(128 sin(frameCount * 0.05) * 128); //text colour
if (mode == 0) {
textSize(20);
textFont(font1);
text("press SPACE to start the game!", 240, 500); //what text to type
}
fill("white");
if (mode == 0) {
textSize(35);
textFont(font2);
text("CATBUS BIZZARE ADVENTURE", 90, 450); //what text to type
}
catBus.y = catBus.y velocity; //code for jumping
velocity = velocity gravity;
if (catBus.y > startY) {
velocity = 0;
catBus.y = startY;
}
catGif.position(catBus.x, catBus.y);
//setCollider("tinyToto")
}
function keyPressed() {
if (keyCode === 32 amp;amp; velocity == 0) {
//spacebar code
mode = 1;
velocity = -upForce;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
Комментарии:
1. Привет 🙂 Милая игра. Пожалуйста, сначала улучшите и очистите свой код; в примере кода, который у вас есть, на самом деле нет отображаемых целей, с которыми нужно столкнуться. Также есть некоторые ненужные переменные и проблемы с отступами и тому подобное ~~ : 3 кроме того, вы можете легко запустить этот код в виде фрагмента, если у вас есть fwonts, wemowe backwound mufic и использовать placekitten.com fow youw spwites и fow the backwound: 3
Ответ №1:
ну, вот как я обычно делаю такие штуки:
function draw(){
for(let i in objects) // objects would be cactuses or birds
if(objects[i].x > player.x amp;amp;
objects[i].x < player.x player.width amp;amp;
objects[i].y > player.y amp;amp;
objects[i].y < player.y player.height){
noLoop()
// maybe do something else here
} // you could also use: for(let object of objects)
}
или, если вы хотите делать классные вещи:
let player = new Player()
class Entity {
hasCollided_pointRect(_x, _y, _width, _height){
if(this.x > _x amp;amp;
this.x < _x _width amp;amp;
this.y > _y amp;amp;
this.y < _y _height){
return true
}
}
}
class Cactus extends Entity {
update(){
if(hasCollided_pointRect(player.x, player.y, player.width, player.height))
lossEvent()
}
}
class Player {
// ...
}
function lossEvent(){
noLoop()
}
это довольно стильный способ сделать это, и для небольшой игры вам действительно не нужно все это
также в MDN есть хорошая статья о rect with rect
amp; point with rect
столкновениях, point with point
столкновение — это просто (x == x amp;amp; y == y)
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
это одна из моих недавних «функций» потери:
if(flag.health <= 0){
noLoop()
newSplashText("You lost!nPress F5 to restart!", "center", "center", 1)
}
Ответ №2:
Способ, которым я обрабатывал игровые состояния в своих играх по обработке, заключался в создании для них отдельных классов. Тогда функция рисования моего основного эскиза выглядела примерно так
fun draw()
{
currentState.draw();
}
Затем каждое игровое состояние действовало как свои собственные эскизы (например, экран меню, воспроизведение, окончание игры и т. Д.) И Имело ссылку на основной эскиз, который создавал состояния. Затем они изменили бы основные currentState
на, то есть на и т.д. new GameOverState()
при необходимости.
На данный момент не беспокойтесь об этом слишком много, если все, что вам нужно, это действительно простой игровой экран с изображением и текстом.
Вместо этого я бы предложил такую структуру. Используйте этот псевдокод в своей основной функции рисования:
fun draw()
{
if (gameOver)
{
// show game over screen
img(gameOver);
text("game over!");
// skip rest of the function
return;
}
// normal game code goes here
foo();
bar();
// update game over after this frame's game code completes
gameOver = checkGameOver();
}
Теперь вам нужен способ проверки на наличие столкновения, чтобы определить результат checkGameOver()
Для обработки столкновений ознакомьтесь с книгой / веб-сайтом Джеффри Томпсона по обработке столкновений. Это потрясающий ресурс, я настоятельно рекомендую вам его проверить.
С веб-сайта, на который я только что ссылался, вот выдержка с веб-сайта, в которой говорится об обработке столкновений между 2d-прямоугольниками.
И вот измененная версия функции обработки столкновений, перечисленная там (я обновил имена переменных, чтобы они были немного более интуитивно понятными)
boolean rectRect(float rect1X, float rect1Y, float rect1Width, float rect1Height, float rect2X, float rect2Y, float rect2Width, float r2h)
{
// are the sides of one rectangle touching the other?
if (rect1X rect1Width >= rect2X amp;amp; // r1 right edge past r2 left
rect1X <= rect2X rect2Width amp;amp; // r1 left edge past r2 right
rect1Y rect1Height >= rect2Y amp;amp; // r1 top edge past r2 bottom
rect1Y <= rect2Y r2h)
{ // r1 bottom edge past r2 top
return true;
}
return false;
Вы можете использовать эту функцию в своей checkGameOver()
функции, которая будет возвращать bool в зависимости от того, соблюдены ли ваши критерии столкновения.
Для вашей игры вы должны перебирать каждое препятствие в своей игре и проверять, перекрываются ли динозавр и препятствие.
Псевдокод:
boolean checkGameOver()
{
foreach (Obstacle obstacle in obstacles)
{
if (rectRect(dino, obstacle))
{
return true;
}
}
return false;
}