Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Вопрос по переменным в классах (http://www.flasher.ru/forum/showthread.php?t=194220)

dimaMJ 10.02.2013 02:38

Вопрос по переменным в классах
 
Вопрос 1 :  как неявно обьявить переменную в классе
Вопрос 2 : как связать эти переменные с onClipEvent(load){ }
помогите решить эти два вопроса из-за них просто плыву в классах
а вообще дело в том что изначально я писал игру в кадрах без классов, все получалось никаких проблем не было, когда выяснялось что нужно (это курсовая) использовать ООП естественно нужно было писать в классах, начал копировать работающие функции из кадров в соответственные классы и все поплыло, постоянно какие то проблемы в основном только с переменными они получаю не те значения которые нужны и я не понимаю как их занести в onClipEvent(load){ } потому что если не занести просто не работает много чего (проверял уже когда в кадрах писал) очень прошу помощи!

  


Hauts 10.02.2013 13:52

Цитата:

Вопрос 1 :  как неявно обьявить переменную в классе
— класс должен быть динамическим, объявление типа такого:
Код AS1/AS2:

this["someVar"] = "someValue";

Цитата:

Вопрос 2 : как связать эти переменные с onClipEvent(load){ }
— Забудьте про код, который пишется на клипах. Если вы создаете экземпляр класса, его переменные могут быть инициализированы в конструкторе, например.

dimaMJ 10.02.2013 14:05

вот даже к примеру у меня есть ф-ция которая прописана в кадре
Код AS1/AS2:

function initGame() {
        // init balloon variables
nextBulletTime = 0;
 
        // init bullet variables
 
        nextBullet = 0;
        bullets = [];
 
        // init score
        score = 0;
}
 
 
function shootBullet() {
 
        // see whether there has been enough time to reload
        if (getTimer() > nextBulletTime) {
                trace(nextBulletTime);
                // create bullet clip
                attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
 
                // set location
                _root["bullet"+nextBullet]._x = _root.cat._x+13;
                _root["bullet"+nextBullet]._y = _root.cat._y+25;
 
                // add to array
                bullets.push(nextBullet);
 
                //get set for next bullet
                nextBullet++;
                nextBulletTime = getTimer()+1000;
                mySound2 = new Sound();
        mySound2.attachSound("booll");
        mySound2.start();
        }
}
 
function moveBullets() {
        // loop through all bullets
        for(i=bullets.length-1;i>=0;i--) {
 
                // get clip
                bullet = _root["bullet"+bullets[i]];
 
 
                        bullet._x += 10;
 
                // see whether it reached top
                if (bullet._x > 750) {
                        bullet.removeMovieClip();
                        bullets.splice(i,1);
 
                // see whether it hit a balloon
                }
                if (bullet.hitTest(_root.lilo) )
                {        _root.lilo.unloadMovie();
                        bullet.removeMovieClip();
                        bullets.splice(i,1);
 
                }
                }

есть код прописанные в кнопке которая находится в рабочей области
Код AS1/AS2:

on (keyPress "<Space>") {
 
 
        _root.shootBullet();
}

и есть код в клипе
Код AS1/AS2:

onClipEvent(load) {
        _root.initGame();
}
 
onClipEvent(enterFrame) {
 
        _root.moveBullets();
 
}

эти ф-ции приводят к тому что персонаж может стрелять по нажатию пробела, мне нужно перевести все это к примеру в 1 класс, как это сделать правильно? у меня не получается может я что то упускаю, может в конструкторе не инициализирую?

Добавлено через 7 минут
вот так я перевел эти ф-ции в класс
Код AS1/AS2:

class Bullets extends MovieClip {
 
 
        var nextBulletTime = 0;
        var nextBullet = 0;
        var bullets = [];
 
 
        function initGame() {
        // init balloon variables
 
 
        // init bullet variables
        var nextBulletTime = 0;
        var nextBullet = 0;
        var bullets = [];
 
        // init score
        var score = 0;
 
}
 
 
function shootBullet() {
 
 
 
        // init score
        var score = 0;
 
        // see whether there has been enough time to reload
        if (getTimer() > nextBulletTime) {
 
                // create bullet clip
                attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
 
                // set location
                _root["bullet"+nextBullet]._x = _root.cat._x+13;
                _root["bullet"+nextBullet]._y = _root.cat._y+25;
 
                // add to array
                bullets.push(nextBullet);
 
                //get set for next bullet
                nextBullet++;
                nextBulletTime = getTimer()+1000;
 
                var mySound2 = new Sound();
        mySound2.attachSound("booll");
        mySound2.start();
        }
}
 
function moveBullets() {
        // loop through all bullets
        for(var i=bullets.length-1;i>=0;i--) {
 
                // get clip
                var bullet = _root["bullet"+bullets[i]];
 
 
                        bullet._x += 10;
 
                // see whether it reached top
                if (bullet._x > 750) {
                        bullet.removeMovieClip();
                        bullets.splice(i,1);
 
                // see whether it hit a balloon
                }
                if (bullet.hitTest(_root.lilo) )
                {        _root.lilo.unloadMovie();
                        bullet.removeMovieClip();
                        bullets.splice(i,1);
 
                }
                }
}
}

это в кнопке
Код AS1/AS2:

on (keyPress "<Space>") {
 
        var Shoot:Bullets = new Bullets;
 
        Shoot.shootBullet();
}

а это в кадре
Код AS1/AS2:

function lod() {
        var Bul:Bullets = new Bullets();
        Bul.initGame();
 
}
 
function game() {
 
        Bul.moveBullets();
}

а это уже в клипе естественно
Код AS1/AS2:

onClipEvent (load)
{
        _root.lod();
}
 
onClipEvent (enterFrame) {
 
 
_root.game();
 
 
}

ошибок не выдает но с помощью trace проверял различные значения, и они принимают не те значения которые принимали в кадре когда были прописаны, что не так?

Hauts 10.02.2013 14:21

Мда. Большая беда.

Код AS1/AS2:

attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);

attachMovie возвращает ссылку на созданный клип. Не нужно потом хитрить с "_root["bullet"+nextBullet]", можно проще:

Код AS1/AS2:

var newBullet = attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
newBullet._x = ...
newBullet._y = ...
 
bullets.push(newBullet)

"nextBullet+9999" у вас глубина, на которую будет положен новый клип. Зачем так неприлично-то на 9999 этажей прыгать-то? Есть же замечательный метод getNextHighestDepth() для этих целей. С этой поправкой получаем следующее решение:

Код AS1/AS2:

var depth = this.getNextHighestDepth();
var newBullet = attachMovie("bullet","bullet_"+depth,depth);
newBullet._x = ...
newBullet._y = ...
 
bullets.push(newBullet)

Вроде нормально. Кроме одного: вы все клипы складываете в один контейнер. В принципе, ничего плохого, но я бы на вашем месте сначала организовал бы слои для игровых объектов. Просто пустых мувиклипов с нужными instance-нэймами накидать на сцене (или создать программно) и не следить за тем, чтобы пуля, например, под "стенками" (или что там у вас) летела.

Теперь насчет кода на клипе. Вы пользуетесь инстанс-нэймами у клипов, и это правильно. Но что вам мешает в том же кадре прописать такой код:

Код AS1/AS2:

initGame();
this.onEnterFrame = moveBullets;

Вы избавитесь от неприятных особенностей, связанных с областью видимости, когда пишете на клипах. Да и переключаться с клипов на кадр не нужно будет.

Кстати, вам initGame-то вообще не нужна. Просто объявили бы все эти переменные в самом начале и все.

Еще одно замечание:
Код AS1/AS2:

for(i=bullets.length-1;i>=0;i--) {

Лучше бы заменить на:
Код AS1/AS2:

for(var i=0; i < bullets.length; i++ ) {

И еще:
Код AS1/AS2:

bullet = _root["bullet"+bullets[i]];

— зачем так сложно-то? Можно проще:
Код AS1/AS2:

var bullet = bullets[k];

У вас же массив bullets объявлен, он будет виден внутри функции moveBullets.

Относительно кнопки, которая ловит нажатие пробела... Убирайте ее и пропишите следующий код в кадре:

Код AS1/AS2:

var keyListener:Object = {};
keyListener.onKeyDown = function(){
    var keyCode == Key.getCode();
    if(keyCode == Key.SPACE){
        // Здесь стреляем
    }
}
Key.addListener(keyListener)

(могу немного ошибаться, пишу по памяти, в хэлпе точно есть примеры)

Добавлено через 5 минут
Обновил страницу, увидел дополнение к вашему посту.

Цитата:

...что не так?
— почти все. Вам требуется сделать все с применением ООП, а вы пытаетесь все по классам распихать, не понимая основных принципов.

Разделите сущности вашей игры по их смыслу и создайте соответствующие классы. Игрок — класс Cat (насколько я понимаю), нужны игровые звуки — создаете класс GameSounds, у которого будете в нужный момент вызвать метод, например, "playShootSound".

Нужен общий класс для того, чтобы создать экземпляры игрока, противников, ландшафта и т.д. и контролировать всю игру — создаете класс GameController.

dimaMJ 10.02.2013 14:27

Цитата:

Сообщение от Hauts (Сообщение 1120024)
— класс должен быть динамическим, объявление типа такого:
Код AS1/AS2:

this["someVar"] = "someValue";


— Забудьте про код, который пишется на клипах. Если вы создаете экземпляр класса, его переменные могут быть инициализированы в конструкторе, например.

то есть типа так
Код AS1/AS2:

dynamic class Bullets extends MovieClip {
this["someVar"] = 5;// так выдает ошибку
 
function game() {
this["someVar"] = 5; // так ошибки нет но когда вывожу значение с помощью trace пишет не определен
}
}

а на счет конструктора не одно и то же просто обьявить переменные я чего то не понимаю просто что он исправит

Hauts 10.02.2013 14:33

Использование динамических классов почти всегда означает ошибку в логике программы. Динамические классы и создание их полей (переменных) на лету (в рантайме) зачастую грозит неправильной работой всего приложения.

Вы же прекрасно знаете, какие поля класа вам потребуются, зачем вам изменяемый класс-то?

Код AS1/AS2:

dynamic class Bullets extends MovieClip {
this["someVar"] = 5;// так выдает ошибку
 
function game() {
this["someVar"] = 5; // так ошибки нет но когда вывожу значение с помощью trace пишет не определен
}
}

Цитата:

this["someVar"] = 5;// так выдает ошибку
— и правильно делает. this в этом месте класса не существует. Класс Экземпляр класса еще не создан, его конструктор не вызывался.

dimaMJ 10.02.2013 14:33

спасибо большое попробую, да я разделил все по классам как вы говорите, но экземпляры создавал в кадре а не в общем классе,

Hauts 10.02.2013 14:38

В кадре просто точку входа создайте. Первый кадр основной временной шкалы:

Код AS1/AS2:

new GameController(this);

А в конструкторе GameController`а уже получите ссылку на временную шкалу. Никаких _root`ов и т.п.

Примерно так:

Код AS1/AS2:

class GameController{
        private var _stageReference:MovieClip;
 
        function GameController(stageReference:MovieClip){
                _stageReference = stageReference;
 
                createLayers();
                createPlayer();
                createLevel();
                initListeners();
 
        }
 
        private function createLayers(){
                // Создаем слои для элементов игры
        }
}

Добавлено через 1 минуту
P.S. В некоторых моментах могу ошибаться, возможно те, кто получше меня соображают, как правильнее написать код игры, меня поправят.

dimaMJ 10.02.2013 15:29

Цитата:

Сообщение от Hauts (Сообщение 1120035)
Теперь насчет кода на клипе. Вы пользуетесь инстанс-нэймами у клипов, и это правильно. Но что вам мешает в том же кадре прописать такой код:

Код AS1/AS2:

initGame();
this.onEnterFrame = moveBullets;

Вы избавитесь от неприятных особенностей, связанных с областью видимости, когда пишете на клипах. Да и переключаться с клипов на кадр не нужно будет.

я не совсем понял вот эти строчки которые нужно прописывать в кадре(точнее строчку, initGame() если убрать) ее ни к чему не привязывать? и не нужно никаких экхемляров создавать у нас же ф-ция moveBullets в классе

Hauts 10.02.2013 15:32

А я не понял вашего вопроса.

Смысл следующий: вы можете назначить мувиклипу в кадре onEnterFrame = function()... , а можете и на самом мувиклипе код прописать onClipEvent(enterframe){... . Так вот первый вариант лучше.


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

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