Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Помогите разобраться с багом в игре змейка (http://www.flasher.ru/forum/showthread.php?t=176499)

Feigi 12.03.2012 13:26

Помогите разобраться с багом в игре змейка
 
Добрый день! Помогите разобраться с багом! Сижу над ним уже 12 часов. Баг в игре змейка. Всё работает хорошо. Кроме того, как змейка сталкивается с левой частью экрана- вылетает непонятная ошибка. Самое странное, что она вылетает после трейс game over , после чего по идее ничего не должно случаться. Error #1010: A term is undefined and has no properties

Заранее большое спасибо!

Код AS3:

package{
 
        import flash.display.Sprite;
        import flash.events.Event;
 
        [SWF(width=600,height=600,backgroundColor=0XD3D1D1,frameRate=5)]
 
 
        public class snakeGame extends Sprite{
 
                private var sprite:Sprite;
                private var game:Game;
 
                public function snakeGame(){
 
                        game=new Game(stage);
 
                }
 
        }
}

Код AS3:

package{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
 
        public class Game{
                private var head:Snake_head;
                private var map:Array;
                private var turnQueue:Array;
                private var direction:uint=40;
                private var sprite:Sprite;
                private var stage:Stage;
                private var paused:Boolean=true;
                private var snake:Vector.<Snake_body>;
                private var bonus:Bonus;
 
                public function Game(stage:Stage){
                        bonus = new Bonus();
                        snake = new Vector.<Snake_body>();
                        this.stage=stage;
                        sprite=new Sprite();
                        stage.addChild(sprite);
                        sprite.graphics.lineStyle(6,0x000000);
                        sprite.graphics.beginFill(0x0095D3);
                        sprite.graphics.drawRect(0, 0, 600,600);
                        sprite.graphics.endFill();
 
                        map=new Array(31);
                        for (var i:int = 0; i < 31; i++) {
                                map[i] = new Array(31);
                        }
 
                        stage.addEventListener(Event.ACTIVATE,onActivate);
 
                        turnQueue=new Array();
 
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, reactToKey);
                        head=new Snake_head;
                        sprite.addChild(head);
                        head.x=310;
                        head.y=10;
                        map[15][0]=head;
                        place_food();
                        head.addEventListener(Event.ENTER_FRAME,onEnterFrame);
 
 
                }
 
                private function onEnterFrame(event:Event):void{
                        if (!paused){
                                var x_:int=head.x;
                                var y_:int=head.y;
                                var segment:Snake_body=new Snake_body();
 
                                if (turnQueue.length!=0)
                                        direction=turnQueue.shift();
 
                                if (direction==37){
                                        head.x-=20;
                                }
                                if (direction==38){
                                        head.y-=20;
                                }
                                if (direction==39){
                                        head.x+=20;
                                }
                                if (direction==40){
                                        head.y+=20;
                                }
                                if(head.x<10 || head.x>590 || head.y<10 || head.y>590)
                                        game_over();
 
                                if (map[(head.x-10)/20][(head.y-10)/20]==1)
                                        game_over();
 
                                if (map[(head.x-10)/20][(head.y-10)/20]==2){
                                        sprite.removeChild(bonus);
                                        segment.x=x_;
                                        segment.y=y_;
                                        map[(x_-10)/20][(y_-10)/20]=1;
                                        snake.push(segment);
                                        sprite.addChild(segment);
                                        place_food();
                                }
                                else{
                                        if (snake.length>0) map[(x_-10)/20][(y_-10)/20]=1;
                                        if (snake.length>0) map[(snake[0].x-10)/20][(snake[0].y-10)/20]=0;
                                        for(var i:int=snake.length-1;i>-1;i--){
                                                var tmp_x:int=snake[i].x;
                                                var tmp_y:int=snake[i].y;
                                                snake[i].x=x_;
                                                snake[i].y=y_;
                                                x_=tmp_x;
                                                y_=tmp_y;
                                        }
                                }
                        }
                }
 
                private function reactToKey(event:KeyboardEvent):void{
                        var keyCode:uint=event.keyCode;
                        if ( Math.abs(direction - keyCode)!=2 &&
                                keyCode > 36 && keyCode < 41 && keyCode!=turnQueue[turnQueue.length-1]){
                                turnQueue.push(keyCode);
 
                        } // arrow keys pressed (37 = left, 38 = up, 39 = right, 40 = down)...
 
                }
 
                private function onDeactivate(e:Event):void {
                        stage.removeEventListener(Event.DEACTIVATE,onDeactivate);
                        stage.addEventListener(Event.ACTIVATE,onActivate);
                        paused=true;
                }
                private function onActivate(e:Event):void {
                        stage.removeEventListener(Event.ACTIVATE,onActivate);
                        stage.addEventListener(Event.DEACTIVATE,onDeactivate);
                        paused=false;
                }
 
                private function place_food():void{
                        var x_:int;
                        var y_:int;
 
                        do{
                                x_= Math.round((Math.random()*29));
                                y_= Math.round((Math.random()*29));
                        }while(map[x_][y_]==1 || (x_*20+10==head.x &&  y_*20+10==head.y) );
                        bonus.x=x_*20+10;
                        bonus.y=y_*20+10;
                        map[x_][y_]=2;
                        sprite.addChild(bonus);
                }
 
                private function game_over():void{
                        paused=true;
                        head.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
                        stage.removeEventListener(KeyboardEvent.KEY_DOWN, reactToKey);
                        trace("game over");
 
                }
 
        }
}


Gaen 12.03.2012 13:36

В будущем используйте тег [АS3][/АS3] для оформления кода.

Чтобы отловить строчку, на которой вылетает ошибка, запустите флешку в режиме отладки.

Feigi 12.03.2012 13:45

Режимом отладки пользовалась. Ошибка описана Error #1010: A term is undefined and has no properties. Больше никакой информации не выдаёт. Пробовала найти ошибку много часов, перед тем как задать вопрос в форум. Если можете помочь- буду рада.

Deimos747 12.03.2012 13:57

На какую строчку ругается?
P.S. Естественно, что ваш код без остальных классов не запускается.

Gaen 12.03.2012 14:00

Ну так важен не только текст ошибки, но и то место, из которого она вываливается. Когда флешка запущена в режиме отладки (ctrl + shift + enter), при возникновении ошибки флеш должен указать на конкретную строчку в коде.

Можно, конечно, долго сидеть и читать код, пытаясь найти ошибку, но зачем тратить время и нервы, когда для этого есть все необходимые инструменты? :)

Feigi 12.03.2012 14:11

Подняла вторую часть кода.
Дебагер жалуется на 75 строчку в объекте Game. Что странно- это случается после trace game over

[SWF] D:\FlashWorkspace\snakeGame\bin-debug\snakeGame.swf - 5,993 bytes after decompression
game over
TypeError: Error #1010: A term is undefined and has no properties.
at Game/onEnterFrame()[D:\FlashWorkspace\snakeGame\src\Game.as:75]

Вообще не понятно, как он дошёл до 75 строки, когда был уже trace game over.
(paused=true).. :)

Genzo 12.03.2012 14:22

Попробуйте :
Код AS3:

                                        if(head.x<10 || head.x>590 || head.y<10 || head.y>590){
                                        game_over();
                                        return;
                                }                       
 
                                if (map[(head.x-10)/20][(head.y-10)/20]==1){
                                        game_over();
                                        return;
                                }


rs7 12.03.2012 14:25

На 75 строчке вызов функции game_over(). Не до конца вы трейс ошибки нам даёте.

Может ошибка где-то в оставшейся части onEnterFrame, он же продолжит выполняться - конструкции return нет.
Или в том месте где у вас обрабатывается turnQueue.

Feigi 12.03.2012 14:42

Return помог, только не понимаю, что он мог изменить. Можете пожалуйста объяснить.

Всё до меня дошло! Он же просто возвращался в функцию. Надо было сделать либо Return либо esle if. Какая тупая ошибка :) Большое спасибо!

HardCoder 12.03.2012 14:43

Вот смотрите: Если мы в аутпуте видим "game over", значит у вас выполняется условие:
Код AS3:

if(head.x<10 || head.x>590 || head.y<10 || head.y>590)
                                        game_over();

То есть, например head.x меньше 10 (так сказано в условии), допустим "7", а y будет к примеру 25. Что происходит дальше:
Код AS3:

if (map[(head.x-10)/20][(head.y-10)/20]==1)

То есть
Код AS3:

if (map[(7-10)/20][(25-10)/20]==1)

Мы получаем элемент массива:
Код AS3:

map[-0.15][0.75]

Вы когда-нибудь видели в массиве индексы -0.15 и 0.75?

Добавлено через 53 секунды
return здесь ничего не решает. То есть он нужен, но сначала исправьте ошибку!

Добавлено через 8 минут
Меня вообще удивляет, как это работает:
Код AS3:

if (map[(head.x-10)/20][(head.y-10)/20]==1)
..............................................................
if (map[(head.x-10)/20][(head.y-10)/20]==2){

Вы же обращаетесь к массиву по НЕЦЕЛЫМ числам...


Часовой пояс GMT +4, время: 14:10.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.