Просмотр полной версии : Вопрос по переменным в классах
Вопрос 1 : как неявно обьявить переменную в классе
Вопрос 2 : как связать эти переменные с onClipEvent(load){ }
помогите решить эти два вопроса из-за них просто плыву в классах
а вообще дело в том что изначально я писал игру в кадрах без классов, все получалось никаких проблем не было, когда выяснялось что нужно (это курсовая) использовать ООП естественно нужно было писать в классах, начал копировать работающие функции из кадров в соответственные классы и все поплыло, постоянно какие то проблемы в основном только с переменными они получаю не те значения которые нужны и я не понимаю как их занести в onClipEvent(load){ } потому что если не занести просто не работает много чего (проверял уже когда в кадрах писал) очень прошу помощи!
Вопрос 1 : как неявно обьявить переменную в классе
— класс должен быть динамическим, объявление типа такого:
this["someVar"] = "someValue";
Вопрос 2 : как связать эти переменные с onClipEvent(load){ }
— Забудьте про код, который пишется на клипах. Если вы создаете экземпляр класса, его переменные могут быть инициализированы в конструкторе, например.
вот даже к примеру у меня есть ф-ция которая прописана в кадре
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);
}
}
есть код прописанные в кнопке которая находится в рабочей области
on (keyPress "<Space>") {
_root.shootBullet();
}
и есть код в клипе
onClipEvent(load) {
_root.initGame();
}
onClipEvent(enterFrame) {
_root.moveBullets();
}
эти ф-ции приводят к тому что персонаж может стрелять по нажатию пробела, мне нужно перевести все это к примеру в 1 класс, как это сделать правильно? у меня не получается может я что то упускаю, может в конструкторе не инициализирую?
Добавлено через 7 минут
вот так я перевел эти ф-ции в класс
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);
}
}
}
}
это в кнопке
on (keyPress "<Space>") {
var Shoot:Bullets = new Bullets;
Shoot.shootBullet();
}
а это в кадре
function lod() {
var Bul:Bullets = new Bullets();
Bul.initGame();
}
function game() {
Bul.moveBullets();
}
а это уже в клипе естественно
onClipEvent (load)
{
_root.lod();
}
onClipEvent (enterFrame) {
_root.game();
}
ошибок не выдает но с помощью trace проверял различные значения, и они принимают не те значения которые принимали в кадре когда были прописаны, что не так?
Мда. Большая беда.
attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
attachMovie возвращает ссылку на созданный клип. Не нужно потом хитрить с "_root["bullet"+nextBullet]", можно проще:
var newBullet = attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
newBullet._x = ...
newBullet._y = ...
bullets.push(newBullet)
"nextBullet+9999" у вас глубина, на которую будет положен новый клип. Зачем так неприлично-то на 9999 этажей прыгать-то? Есть же замечательный метод getNextHighestDepth() для этих целей. С этой поправкой получаем следующее решение:
var depth = this.getNextHighestDepth();
var newBullet = attachMovie("bullet","bullet_"+depth,depth);
newBullet._x = ...
newBullet._y = ...
bullets.push(newBullet)
Вроде нормально. Кроме одного: вы все клипы складываете в один контейнер. В принципе, ничего плохого, но я бы на вашем месте сначала организовал бы слои для игровых объектов. Просто пустых мувиклипов с нужными instance-нэймами накидать на сцене (или создать программно) и не следить за тем, чтобы пуля, например, под "стенками" (или что там у вас) летела.
Теперь насчет кода на клипе. Вы пользуетесь инстанс-нэймами у клипов, и это правильно. Но что вам мешает в том же кадре прописать такой код:
initGame();
this.onEnterFrame = moveBullets;
Вы избавитесь от неприятных особенностей, связанных с областью видимости, когда пишете на клипах. Да и переключаться с клипов на кадр не нужно будет.
Кстати, вам initGame-то вообще не нужна. Просто объявили бы все эти переменные в самом начале и все.
Еще одно замечание:
for(i=bullets.length-1;i>=0;i--) {
Лучше бы заменить на:
for(var i=0; i < bullets.length; i++ ) {
И еще:
bullet = _root["bullet"+bullets[i]];
— зачем так сложно-то? Можно проще:
var bullet = bullets[k];
У вас же массив bullets объявлен, он будет виден внутри функции moveBullets.
Относительно кнопки, которая ловит нажатие пробела... Убирайте ее и пропишите следующий код в кадре:
var keyListener:Object = {};
keyListener.onKeyDown = function(){
var keyCode == Key.getCode();
if(keyCode == Key.SPACE){
// Здесь стреляем
}
}
Key.addListener(keyListener)
(могу немного ошибаться, пишу по памяти, в хэлпе точно есть примеры)
Добавлено через 5 минут
Обновил страницу, увидел дополнение к вашему посту.
...что не так?
— почти все. Вам требуется сделать все с применением ООП, а вы пытаетесь все по классам распихать, не понимая основных принципов.
Разделите сущности вашей игры по их смыслу и создайте соответствующие классы. Игрок — класс Cat (насколько я понимаю), нужны игровые звуки — создаете класс GameSounds, у которого будете в нужный момент вызвать метод, например, "playShootSound".
Нужен общий класс для того, чтобы создать экземпляры игрока, противников, ландшафта и т.д. и контролировать всю игру — создаете класс GameController.
— класс должен быть динамическим, объявление типа такого:
this["someVar"] = "someValue";
— Забудьте про код, который пишется на клипах. Если вы создаете экземпляр класса, его переменные могут быть инициализированы в конструкторе, например.
то есть типа так dynamic class Bullets extends MovieClip {
this["someVar"] = 5;// так выдает ошибку
function game() {
this["someVar"] = 5; // так ошибки нет но когда вывожу значение с помощью trace пишет не определен
}
}
а на счет конструктора не одно и то же просто обьявить переменные я чего то не понимаю просто что он исправит
Использование динамических классов почти всегда означает ошибку в логике программы. Динамические классы и создание их полей (переменных) на лету (в рантайме) зачастую грозит неправильной работой всего приложения.
Вы же прекрасно знаете, какие поля класа вам потребуются, зачем вам изменяемый класс-то?
dynamic class Bullets extends MovieClip {
this["someVar"] = 5;// так выдает ошибку
function game() {
this["someVar"] = 5; // так ошибки нет но когда вывожу значение с помощью trace пишет не определен
}
}
this["someVar"] = 5;// так выдает ошибку — и правильно делает. this в этом месте класса не существует. Класс Экземпляр класса еще не создан, его конструктор не вызывался.
спасибо большое попробую, да я разделил все по классам как вы говорите, но экземпляры создавал в кадре а не в общем классе,
В кадре просто точку входа создайте. Первый кадр основной временной шкалы:
new GameController(this);
А в конструкторе GameController`а уже получите ссылку на временную шкалу. Никаких _root`ов и т.п.
Примерно так:
class GameController{
private var _stageReference:MovieClip;
function GameController(stageReference:MovieClip){
_stageReference = stageReference;
createLayers();
createPlayer();
createLevel();
initListeners();
}
private function createLayers(){
// Создаем слои для элементов игры
}
}
Добавлено через 1 минуту
P.S. В некоторых моментах могу ошибаться, возможно те, кто получше меня соображают, как правильнее написать код игры, меня поправят.
Теперь насчет кода на клипе. Вы пользуетесь инстанс-нэймами у клипов, и это правильно. Но что вам мешает в том же кадре прописать такой код:
initGame();
this.onEnterFrame = moveBullets;
Вы избавитесь от неприятных особенностей, связанных с областью видимости, когда пишете на клипах. Да и переключаться с клипов на кадр не нужно будет.
я не совсем понял вот эти строчки которые нужно прописывать в кадре(точнее строчку, initGame() если убрать) ее ни к чему не привязывать? и не нужно никаких экхемляров создавать у нас же ф-ция moveBullets в классе
А я не понял вашего вопроса.
Смысл следующий: вы можете назначить мувиклипу в кадре onEnterFrame = function()... , а можете и на самом мувиклипе код прописать onClipEvent(enterframe){... . Так вот первый вариант лучше.
вот обьясните мне почему в этом коде (комментарий читайте ниже)
var nextBulletTime = 0;
var nextBullet = 0;
var bullets = [];
// init score
var score = 0;
function shootBullet() {
// init score
// see whether there has been enough time to reload
if (getTimer() > nextBulletTime) {
trace(nextBulletTime); // почему тут выводит ноль? когда должно выводить сначала 0 потом
//(getTimer()+1000;) а оно постоянно дает ноль из-за чего паузы совсем нет ну я не пойму
var depth = this.getNextHighestDepth();
var newBullet = attachMovie("bullet","bullet_"+nextBullet,depth);
newBullet._x =_root.cat._x+13;
newBullet._y = _root.cat._y+25;
bullets.push(newBullet);
//get set for next bullet
nextBullet++;
nextBulletTime = getTimer()+1000;
var mySound2 = new Sound();
mySound2.attachSound("booll");
mySound2.start();
}
}
Ноль дает в самом начале. Так как вы инициализировали переменную с таким значением.
Ctrl + Shift + F автоформатирование кода.
Кстати я бы чуток подправил бы код. Вам nextBullet не нужно скорее всего (достаточно использовать "bullet_"+depth для имени новой пули). Если нужно — тогда ассоциативное название не помешало бы, например, bulletCounter (счетчик пуль).
И вынес бы в отдельную переменную минимальную задержку перед следующим выстрелом, например так:
var nextShootDelay = 1000;
Чтобы можно было потом подправить в одном месте это значение, а не искать по коду, где эти задержки используются.
Добавлено через 4 минуты
Да, и изначальное значение для nextBulletTime поставил бы -nextShootDelay , чтобы можно было сразу при старте игры стрелять, а не ждать, пока пауза пройдет.
всеравно суть та я понял задержки но сделать ее не получается значение nextBulletTime остается одинаковым и не меняется,может цикл другой поставить просто я считал что эта строка
nextBulletTime = getTimer()+1000; будет постоянно менять значение nextBulletTime при вызове ф-ции нажатием кнопки а значение всегда остается таким каким я его задал к примеру если будет 1000 изначально будет задержка а потом как время таймера станет больше 1000 все задержки нет уже
dimaMJ, не забывайте про запятые и точки, на форуме принято грамотно писать :)
var nextBulletTime = 0;
function shootBullet() {
if (getTimer() > nextBulletTime) {
trace(nextBulletTime);
nextBulletTime = getTimer() + 1000;
}
}
var keyListener = {};
keyListener.onKeyDown = function() {
if (Key.getCode() == Key.SPACE) {
shootBullet();
}
};
Key.addListener(keyListener);
У меня все работает, я не совсем понимаю, в чем у вас проблема.
var keyListener = {};
keyListener.onKeyDown = function() {
if (Key.getCode() == Key.SPACE) {
shootBullet();
}
};
Key.addListener(keyListener);[/AS]
а где вы это прописывали? в кадре или в классе? класс ругается почему то
- Этот оператор в определении класса недопустимо.
Весь код из моего предыдущего сообщения я прописал в кадре.
добавил событие кнопки в кадр и получается такое что при нажатии пробела один раз сначала выводит много нулей, а когда второй раз то вот такое
0
0
0
7167
7185
7185
7185
7185
7185
7185
7185
7185
7185
7185
7185
7185
7185
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7186
7187
7187
7187
7187
7187
7187
0
0
0
0
дело в том что у меня при нажатии еще вызывается звук и он как то ужасно искажается от этого
Если вы тестируете во флэше (в среде разработки), то зайдите в меню плеера (при тестировании) "Control" и щелкните "Disable keyboard shortcuts". Что-то мне подсказывает, что у вас там несколько кадров, а по нажатию на пробел (при отладке), у вас включается воспроизведение.
Хотя я не уверен.
сделал ничего не изменилось странно как то при зажатии пробела паузы нет
dimaMJ, не забывайте про запятые, точки и большие буквы в начале предложений. Серьезно, правила для всех, не дожидайтесь замечаний от модераторов.
Выкладывайте исходник тестовый, посмотрю, как время будет.
Ребята ну мне нужна помощь, что там?
что не открывается, у меня все открывается
dimaMJ, вероятно, ваш файл FLA сохранен из версии Adobe Flash CS6 в соответствующем формате по умолчанию. Не все флешеры могут открыть такой исходник, эта программа еще достаточно нова и не всем доступна. Пересохраните исходник в как можно более ранней версии.
И еще - предложения пишите с заглавных букв, а заканчивайте точкой или другими знаками препинания, у нас действуют правила грамматики. Это правило форума.
Вроде перезаписал в версию CS5, вот.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.