Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Clojure蛇跳过位置_Java_Swing_Clojure_Keyboard Events - Fatal编程技术网

Java Clojure蛇跳过位置

Java Clojure蛇跳过位置,java,swing,clojure,keyboard-events,Java,Swing,Clojure,Keyboard Events,我是一个Clojure初学者,我一直在玩这里提供的蛇游戏代码。当我运行游戏时,蛇似乎在移动时跳过了位置,它并不像我预期的那样一个接一个地移动。但当我转动蛇并按住方向键时,它开始正常动作,一个方块接一个方块地移动,一旦我松开方向键,它就会再次开始跳跃。我想这与Swing使用组件或处理事件的方式有关,但我还没有弄明白或调试它。我希望我的蛇能一方块一方块地移动,即使我没有按住钥匙也不会跳。这是我的代码,它与我给出的链接基本相同,只是在空间和墙壁方面做了一些小的修改: (ns app.core (:

我是一个Clojure初学者,我一直在玩这里提供的蛇游戏代码。当我运行游戏时,蛇似乎在移动时跳过了位置,它并不像我预期的那样一个接一个地移动。但当我转动蛇并按住方向键时,它开始正常动作,一个方块接一个方块地移动,一旦我松开方向键,它就会再次开始跳跃。我想这与Swing使用组件或处理事件的方式有关,但我还没有弄明白或调试它。我希望我的蛇能一方块一方块地移动,即使我没有按住钥匙也不会跳。这是我的代码,它与我给出的链接基本相同,只是在空间和墙壁方面做了一些小的修改:

(ns app.core
  (:import (java.awt Color Dimension)
           (javax.swing JPanel JFrame Timer JOptionPane WindowConstants)
           (java.awt.event ActionListener KeyListener))
  (:use app.util.import-static))
(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)

; ---------------------------------------------------------------------
; functional model
; ---------------------------------------------------------------------
; constants to describe time, space and motion
(def width 19)
(def height 10)
(def point-size 25)
(def turn-millis 150)
(def win-length 500)
(def dirs {VK_LEFT  [-1 0]
           VK_RIGHT [1 0]
           VK_UP    [0 -1]
           VK_DOWN  [0 1]})

; math functions for game board
(defn add-points [& pts]
  (vec (apply map + pts)))

(defn point-to-screen-rect [pt]
  (map #(* point-size %)
       [(pt 0) (pt 1) 1 1]))

; function for creating an apple
(defn create-apple []
  {:location [(rand-int width) (rand-int height)]
   :color (Color. 210 50 90)
   :type :apple})

; function for creating a snake
(defn create-snake []
  {:body (list [1 1])
   :dir [1 0]
   :type :snake
   :color (Color. 15 160 70)})

; function for moving a snake
(defn move [{:keys [body dir] :as snake} & grow]
  (assoc snake :body (cons (add-points (first body) dir)
                           (if grow body (butlast body)))))

; function for checking if the player won
(defn win? [{body :body}]
  (>= (count body) win-length))

; function for checking if the player lost the game,
; which means that head of the snake has overlaped
; with its body
(defn head-overlaps-body? [{[head & body] :body}]
  (contains? (set body) head))

(defn out-of-bounds? [{[head] :body}]
  (or (< (head 0) 0)
      (> (head 0) width)
      (< (head 1) 0)
      (> (head 1) height)))

(defn lose? [snake]
  (or (head-overlaps-body? snake) (out-of-bounds? snake)))

; function for checking if the snake eats an apple
; (check if head location equals apple location)
(defn eats? [{[snake-head] :body} {apple :location}]
  (= snake-head apple))

; function that changes direction
(defn turn [snake newdir]
  (assoc snake :dir newdir))

; ---------------------------------------------------------------------
; mutable model
; ---------------------------------------------------------------------
; function that resets the game state
(defn reset-game [snake apple]
  (dosync (ref-set snake (create-snake))
          (ref-set apple (create-apple)))
  nil)

; function for updating direction of snake
(defn update-direction [snake newdir]
  (when newdir (dosync (alter snake turn newdir))))

; function for updating positions of snake and apple
(defn update-positions [snake apple]
  (dosync
    (if (eats? @snake @apple)
      (do (ref-set apple (create-apple))
          (alter snake move :grow))
      (alter snake move)))
  nil)

; ---------------------------------------------------------------------
; gui
; ---------------------------------------------------------------------
; function for making a point on the screen
(defn fill-point [g pt color]
  (let [[x y width height] (point-to-screen-rect pt)]
    (.setColor g color)
    (.fillRect g x y width height)))


; function for painting snakes and apples
(defmulti paint (fn [g object & _] (:type object)))

(defmethod paint :apple [g {:keys [location color]}]
  (fill-point g location color))

(defmethod paint :snake [g {:keys [body color]}]
  (doseq [point body]
    (fill-point g point color)))

; game panel
(defn game-panel [frame snake apple]
  (proxy [JPanel ActionListener KeyListener] []
    (paintComponent [g]
      (proxy-super paintComponent g)
      (paint g @snake)
      (paint g @apple))
    (actionPerformed [e]
      (update-positions snake apple)
      (when (lose? @snake)
        (reset-game snake apple)
        (JOptionPane/showMessageDialog frame "Game over!"))
      (when (win? @snake)
        (reset-game snake apple)
        (JOptionPane/showMessageDialog frame "You win!"))
      (.repaint this))
    (keyPressed [e]
      (update-direction snake (dirs (.getKeyCode e))))
    (getPreferredSize []
      (Dimension. (* (inc width) point-size)
                  (* (inc height) point-size)))
    (keyReleased [e])
    (keyTyped [e])))

; main game function
(defn game []
  (let [snake (ref (create-snake))
        apple (ref (create-apple))
        frame (JFrame. "Snake")
        panel (game-panel frame snake apple)
        timer (Timer. turn-millis panel)]
    (doto panel
      (.setFocusable true)
      (.addKeyListener panel))
    (doto frame
      (.add panel)
      (.pack)
      (.setVisible true)
      (.setResizable false)
      (.setDefaultCloseOperation WindowConstants/EXIT_ON_CLOSE))
    (.start timer)
    [snake, apple, timer]))
(ns app.core
(:导入(java.awt颜色维度)
(javax.swing JPanel JFrame Timer JOptionPane WindowConstants)
(java.awt.event ActionListener KeyListener))
(:使用app.util.import static))
(导入静态java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)
; ---------------------------------------------------------------------
; 功能模型
; ---------------------------------------------------------------------
; 描述时间、空间和运动的常数
(def宽度19)
(def高度10)
(def点大小25)
(def转数毫秒150)
(def win长度500)
(def dirs{VK_左[-10]
VK_右[10]
VK_UP[0-1]
VK_向下[0 1]})
; 游戏板的数学函数
(定义添加点[&pts]
(vec(应用map+pts)))
(定义点至屏幕矩形[pt]
(地图#(*点大小%)
[(第0部分)(第1部分)1]))
; 用于创建苹果的函数
(defn创建苹果[]
{:位置[(rand int width)(rand int height)]
:颜色(颜色:210 50 90)
:type:apple})
; 用于创建蛇的函数
(defn创建snake[]
{:正文(列表[1])
:dir[10]
:类型:蛇
:颜色(颜色15 160 70)}
; 移动蛇的功能
(defn move[{:keys[body dir]:as snake}&grow]
(助理蛇:主体(cons)(添加点(第一主体)方向)
(如果是生长体(但最后一个体((()))))
; 用于检查玩家是否获胜的功能
(defn-win?[{body:body}]
(>=(计数主体)赢得长度)
; 用于检查玩家是否输掉游戏的功能,
; 这意味着蛇头已经重叠了
; 用它的身体
(defn head与body重叠?[{[head&body]:body}]
(包含?(集合体)头部)
(defn越界?[{[head]:body}]
(或(<(总目0)0)
(>(头部0)宽度)
(<(总目1)0)
(>(头部1)高度)
(德文输了?[蛇]
(或(头部与身体重叠?蛇)(出界?蛇)))
; 用于检查蛇是否吃苹果的函数
; (检查头部位置是否等于苹果位置)
(defn吃?[{[蛇头]:身体}{苹果:位置}]
(蛇头苹果)
; 改变方向的功能
(反方向转弯[蛇形新方向]
(助理署长(新署长))
; ---------------------------------------------------------------------
; 可变模型
; ---------------------------------------------------------------------
; 重置游戏状态的函数
(defn重置游戏[蛇苹果]
(dosync(参考集snake(创建snake))
(参考设置苹果(创建苹果)))
零)
; 用于更新snake的方向的函数
(defn更新方向[snake newdir]
(当newdir(dosync(alter snake turn newdir))时)
; 更新snake和apple位置的功能
(defn更新位置[snake apple]
(dosync)
(如果(吃?@snake@apple)
(do(参考设置苹果(创建苹果))
(改变蛇的移动:成长)
(改变蛇行)
零)
; ---------------------------------------------------------------------
; 桂
; ---------------------------------------------------------------------
; 在屏幕上显示点的功能
(定义填充点[g pt颜色]
(让[[x y宽度高度](指向屏幕矩形部分)]
(.setColor g color)
(.fillRect g x y宽度高度)))
; 画蛇和苹果的功能
(defmulti-paint(fn[g对象和类型对象)))
(defmethod paint:apple[g{:keys[location color]}]
(填充点g位置颜色))
(defmethod paint:snake[g{:keys[车身颜色]}]
(doseq[点体]
(填充点g点颜色)))
; 游戏面板
(defn游戏面板[框架蛇苹果]
(代理[JPanel ActionListener KeyListener][]
(b)组件[g]
(代理超级油漆组件g)
(画g@snake)
(苹果漆g)
(执行的行动[e]
(苹果更新位置)
(何时(输?@snake)
(重置游戏蛇苹果)
(JOptionPane/ShowMessage对话框框“游戏结束!”)
(何时(赢?@snake)
(重置游戏蛇苹果)
(JOptionPane/ShowMessage对话框框“您赢了!”)
(.重新粉刷)
(按[e]键)
(更新方向蛇(dirs(.getKeyCode e)))
(getPreferredSize[]
(尺寸。(*(包括宽度)点大小)
(*(包括高度)点大小)
(密钥释放[e])
(键入[e]))
; 主要游戏功能
(defn游戏[]
(让[蛇(参考(创建蛇))
苹果(参考(创建苹果))
框架(JFrame,“蛇”)
面板(游戏面板框架蛇苹果)
计时器(计时器转动毫秒面板)]
(doto小组)
(.setFocusable-true)
(.addKeyListener面板)
(doto框架)
(.添加面板)
(.包装)
(.setVisible-true)
(.SetResizeable false)
(.SetDefaultCloseOperationWindowConstants/EXIT_ON_CLOSE))
(.启动计时器)
[蛇,苹果,计时器])
编辑:

我也在这里尝试了这个实现,它也有同样的问题。这可能是与挥杆有关的问题。我正在考虑使用跷跷板库,但因为它是Swing的包装器,所以问题可能会一直存在