日常の進捗

主に自分のための,行為とその習慣化の記録

Mod:Coding Challenge #3: The Snake Game

スネークゲーム。チュートリアルでは🐍を矢印キーで動かすものだったが、操作するの面倒だったので、🐍が自動で餌を追従するようにプログラムを書き換えた。気分を変えようとp5.jsで書いてみた。

var snake;
var scl = 10;

var food;

function setup() {
  createCanvas(600,600);
  colorMode(HSB,360,100,100,100);
  snake = new Snake();
  frameRate(30);
  pickLocation();
  rectMode(CENTER);
}

function pickLocation(){
  var cols = floor(width/scl);
  var rows = floor(height/scl);
  food = createVector(floor(random(cols)),floor(random(rows)));
  food.mult(scl);
}


function draw() {
  background(30,20,100);
  snake.update();
  snake.draw();
  
  if(snake.eat(food)){
    pickLocation();
  }
  
  noStroke();
  fill(30,100,100);
  rect(food.x,food.y,scl,scl);
}



function keyPressed(){
    if(keyCode === UP_ARROW){
        snake.dir(0,-1);
    }else if (keyCode === DOWN_ARROW){
        snake.dir(0,1);
    }else if (keyCode === RIGHT_ARROW){
        snake.dir(1,0);    
    }else if (keyCode === LEFT_ARROW){
        snake.dir(-1,0);
    }
}

function Snake(){
  this.x = 0;
  this.y = 0;
  this.xSpeed = 1;
  this.ySpeed = 0;
  this.life = 1;  
  this.total = 1;
  this.tail = [];
  
  this.update = function(){
    var theta = atan2(food.y-this.y,food.x-this.x);
    var angle = int(degrees(theta));
    if(angle >0 && angle < 90){
        this.dir(1,0);
    }else if(angle >90 && angle < 180){
        this.dir(-1,0);
    }else if(angle === 90){
        this.dir(0,1);
    }else if(angle < 0 && angle > -90){
        this.dir(1,0);
    }else if(angle < -90 && angle > -180){
        this.dir(0,-1);
    }else if(angle === -90){
        this.dir(0,-1);
    }else if(angle === 180){
        this.dir(-1,0);
    }else if(angle === 0){
        this.dir(1,0);
    }
    
    for(var i = 0; i < this.tail.length-1; i++){
        this.tail[i] = this.tail[i+1];
    }
    this.tail[this.total-1] = createVector(this.x,this.y);

    this.x = this.x + this.xSpeed*scl;
    this.y = this.y + this.ySpeed*scl;
    
    this.x = constrain(this.x,0,width-scl);
    this.y = constrain(this.y,0,height-scl);    
    
    this.life -= 0.015;
    if(this.life <0){
      this.life = 1;
      this.death();
    }
  }
  
  this.eat = function(pos){
    var d = dist(this.x,this.y,food.x,food.y);
    if(d < 1){
      this.total++;
      return true;
    }else{
        return false;
    }
  }
  
  this.draw = function(){
    fill(150,80,80);
    for(var i = 0; i < this.total-1; i++){
      push();
      translate(this.tail[i].x,this.tail[i].y);
      rotate(((i*10+frameCount))*0.15);
      rect(0,0,scl*0.75,scl*1.5);
      pop();
    }
    push();
    translate(this.tail[this.total-1].x,this.tail[this.total-1].y);
    rotate(atan2(this.ySpeed,this.xSpeed));
    var thetaMouth = map(sin(frameCount*0.5),-1,1,PI/4,0);
    arc(0,0,scl*1.5,scl*1.5,thetaMouth,TWO_PI-thetaMouth);
    pop();
  }
  this.dir = function(x,y){
    this.xSpeed = x;
    this.ySpeed = y;
  }
  
  this.death = function(){
    if(this.total > 1){
    this.tail.shift();
    this.total -= 1;
    }
  }

}