[HTML, CSS, JS] class로 만들어보는 간단한 2D 게임 2 (collision detection)

김범기·2024년 7월 18일

JAVASCRIPT

목록 보기
38/38
post-thumbnail

지난 시간에 이어서..

필요없어진 장애물을 제거 하자.

let timer = 0
let cactus여러개 = []

function 프레임마다실행할거(){
  requestAnimationFrame(프레임마다실행할거)
  timer++

  ctx.clearRect(0,0, canvas.width, canvas.height)
  
  //  2~ 3초에 한 번 이거 실행하며 됨. XX프레임 마다 실행시키면 됨
  if(timer % 120 == 0){
    let cactus = new Cactus()
    cactus여러개.push(cactus)
    cactus.draw()
  }
  
  cactus여러개.forEach((a, i, o) => {
    //x 좌표가 0미만이면 제거.
    if(a.x < 0 ){
      o.splice(i, 1)
    }
    a.x -= 1
    a.draw()
  })
  dino.draw()
}
프레임마다실행할거()

화면을 넘어가면 없어지도록 해주자.

점프도 구현해주자.
스페이스바를 누르면 점프하게!

변수를 이용해서 점프와 다시 내려오는 것을 구현해줬다.

let timer = 0
let cactus여러개 = []
let 점프중 = false
let 점프tiemr = 0

function 프레임마다실행할거(){
  requestAnimationFrame(프레임마다실행할거)
  timer++

  ctx.clearRect(0,0, canvas.width, canvas.height)
  
  //  2~ 3초에 한 번 이거 실행하며 됨. XX프레임 마다 실행시키면 됨
  if(timer % 120 == 0){
    let cactus = new Cactus()
    cactus여러개.push(cactus)
    cactus.draw()
  }
  
  cactus여러개.forEach((a, i, o) => {
    //x 좌표가 0미만이면 제거.
    if(a.x < (0 - this.x)){
      o.splice(i, 1)
    }
    a.x -= 1
    a.draw()
  })
  dino.draw()

  if(점프중 == true){
    dino.y -= 1
    점프tiemr += 1
  }
  if(점프중 == false){
    if(dino.y < 200){
      dino.y += 1
    }
  }
  if(점프tiemr > 100){
    점프중 = false
    점프tiemr = 0
  }
}
프레임마다실행할거()


document.addEventListener('keydown', function(e){
  if(e.code === 'Space'){
    점프중 = true
  }
})

충돌을 감지하자!!!!!

let timer = 0
let cactus여러개 = []
let 점프중 = false
let 점프tiemr = 0
var animation

function 프레임마다실행할거(){
  animation = requestAnimationFrame(프레임마다실행할거)
  timer++

  ctx.clearRect(0,0, canvas.width, canvas.height)
  
  //  2~ 3초에 한 번 이거 실행하며 됨. XX프레임 마다 실행시키면 됨
  if(timer % (120) == 0){
    let cactus = new Cactus()
    cactus여러개.push(cactus)
    cactus.draw()
  }
  
  cactus여러개.forEach((a, i, o) => {
    //x 좌표가 0미만이면 제거.
    if(a.x < (0 - this.x)){
      o.splice(i, 1)
    }
    a.x -= 3

    //충돌체크는 여기서 해야하겠지"? 왜냐하면 주인공VS모든 장애물 충돌체크가 필요하니까
    충돌하냐(dino, a)

    a.draw()
  })
  dino.draw()

  if(점프중 == true){
    dino.y -= 4
    점프tiemr += 1
  }
  if(점프중 == false){
    if(dino.y < 200){
      dino.y += 4
    }
  }
  if(점프tiemr > 50){
    점프중 = false
    점프tiemr = 0
  }
}
프레임마다실행할거()


// 충돌확인
function 충돌하냐(dino, cactus){
  let x축차이 = cactus.x - (dino.x + dino.width)
  let y축차이 = cactus.y - (dino.y + dino.height)
  if(x축차이 < 0 && y축차이 < 0){
    ctx.clearRect(0,0, canvas.width, canvas.height)
    cancelAnimationFrame(animation)
  }
  // console.log('충돌')
}

전체코드는 아래와 같다.

let canvas = document.getElementById('canvas')
let ctx = canvas.getContext('2d')

canvas.width = window.innerWidth  - 100
canvas.height = window.innerHeight  - 100

let img2 = new Image()
img2.src = 'dinosaur.png'

let dino = {
  x : 10,
  y : 200,
  width : 50,
  height : 50,
  draw(){
    ctx.fillStyle = 'green'
    ctx.fillRect(this.x, this.y, this.width, this.height)
    ctx.drawImage(img2, this.x, this.y, this.width, this.height)
  }
}
dino.draw()
let img1 = new Image()
img1.src = 'cactus.png'

class Cactus {
  constructor(){
    this.x = 500
    this.y = 200
    this.width = 50
    this.height = 50
  }
  draw(){
    ctx.fillStyle = 'red'
    ctx.fillRect(this.x, this.y, this.width, this.height)
    ctx.drawImage(img1, this.x, this.y, this.width, this.height)
  }
}

let timer = 0
let cactus여러개 = []
let 점프중 = false
let 점프tiemr = 0
let animate

function 프레임마다실행할거(){
  animate = requestAnimationFrame(프레임마다실행할거)
  timer++

  ctx.clearRect(0,0, canvas.width, canvas.height)
  
  //  2~ 3초에 한 번 이거 실행하며 됨. XX프레임 마다 실행시키면 됨
  if(timer % (120) == 0){
    let cactus = new Cactus()
    cactus여러개.push(cactus)
    cactus.draw()
  }
  
  cactus여러개.forEach((a, i, o) => {
    //x 좌표가 0미만이면 제거.b 
    if(a.x < 0){
      o.splice(i, 1)
    }
    a.x -= 3

    //충돌체크는 여기서 해야하겠지"? 왜냐하면 주인공VS모든 장애물 충돌체크가 필요하니까
    충돌하냐(dino, a)

    a.draw()
  })
  dino.draw()

  if(점프중 == true){
    dino.y -= 4
    점프tiemr += 1
  }
  if(점프중 == false){
    if(dino.y < 200){
      dino.y += 4
    }
  }
  if(점프tiemr > 40){
    점프중 = false
    점프tiemr = 0
  }
}
프레임마다실행할거()


// 충돌확인
function 충돌하냐(dino, cactus){
  let x축차이 = cactus.x - (dino.x + dino.width);
  let y축차이 = cactus.y - (dino.y + dino.height);

  if ( x축차이 < 0  && y축차이 < 0 ){
    ctx.clearRect(0,0, canvas.width, canvas.height);
    cancelAnimationFrame(animate);
  }
}


document.addEventListener('keydown', function(e){
  if(e.code === 'Space'){
    점프중 = true
  }
})


선인장

공룡

제대로 작동시키려면

profile
반드시 결승점을 통과하는 개발자

0개의 댓글