ELM:防止游戏元素相互碰撞/定位

时间:2016-03-19 09:22:47

标签: elm

我正在考虑用2艘船来制作游戏。

船舶可以向上,向下,向左或向右移动。一艘船由箭头控制,另一艘由WASD控制。

但是我想防止船只相互定位。

所以在我的例子中,蓝色船不应该位于红色船的顶部。我希望如果红船向右移动并击中蓝色的船 - 两艘船都不会移动。

感谢任何帮助。

GIST

module Game (..) where

import Graphics.Element exposing (..)
import Graphics.Collage exposing (..)
import Color exposing (red, blue, gray, green)
import Keyboard
import Window


-- ALIAS


type alias Model =
  { color : Color.Color
  , isFiring : Bool
  , name : String
  , y : Int
  , x : Int
  }


-- MODEL


initialShip : String -> Model
initialShip name =
  let
    color =
      if name == "ship1" then
        red
      else
        blue
  in
    { color = color
    , isFiring = False
    , name = name
    , y = 0
    , x = 0
    }


-- POSITIONS


moveLeft : Model -> Model
moveLeft model =
  { model | x = model.x - 1 }

moveRight : Model -> Model
moveRight model =
  { model | x = model.x + 1 }


moveDown : Model -> Model
moveDown model =
  { model | y = model.y - 1 }


moveUp : Model -> Model
moveUp model =
  { model | y = model.y + 1 }


-- ACTIONS


type Action
  = NoOp
  | Left
  | Right
  | Down
  | Up


-- UPDATE


update : Action -> Model -> Model
update action model =
  case action of
    NoOp ->
      model

    Left ->
      moveLeft model

    Right ->
      moveRight model

    Down ->
      moveDown model

    Up ->
      moveUp model


-- View


drawGame : Float -> Float -> Form
drawGame w h =
  rect w h
    |> filled gray


drawShip : Float -> Model -> Form
drawShip gameHeight ship =
  let
    shipColor =
      if ship.isFiring then green else ship.color

    initialPosition =
      if ship.name == "ship1" then
        (toFloat (ship.x - 50))
      else
        (toFloat (ship.x + 50))
  in
    ngon 3 30
      |> filled shipColor
      |> rotate (degrees 90)
      |> move (initialPosition, (toFloat ship.y + 50))


view : (Int, Int) -> Model -> Model -> Element
view (w, h) ship1 ship2 =
  let
    (w', h') = (toFloat w, toFloat h)
  in
    collage w h
      [ drawGame w' h'
        , drawShip h' ship1
        , drawShip h' ship2
      ]


-- SIGNALS

direction : Signal { x : Int, y : Int } -> Signal Action
direction input =
  let
    position =
      Signal.map (\{ x, y } -> { x = x, y = y }) input

    delta =
      Time.fps 120

    toAction { x, y } =
      if x < 0 then
        Left
      else if x > 0 then
        Right
      else if y < 0 then
        Down
      else if y > 0 then
        Up
      else
        NoOp

    actions =
      Signal.map toAction position
  in
    Signal.sampleOn delta actions


ship1 : Signal Model
ship1 =
  Signal.foldp update (initialShip "ship1") (direction Keyboard.wasd)


ship2 : Signal Model
ship2 =
  Signal.foldp update (initialShip "ship2") (direction Keyboard.arrows)


-- MAIN


main : Signal Element
main =
  Signal.map3 view Window.dimensions ship1 ship2

1 个答案:

答案 0 :(得分:0)

我建议使用包含两个船只的单个模型,然后制作具有箭头和wasd的数据类型,然后映射箭头信号和wasd信号并将它们合并为单个foldp。