|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Feb 2013
Сообщений: 11
|
Sprite не желает становится растровым
Добрый вечер знатокам, помогите решить задачу!
У меня рисуется экземпляр Спрайта (а точнее, класса Litera) пользователем (с помощью "мела"-мыши - класс Chalk) на доске (класс Desk). Затем я хочу перевести его в растр (по правому клику мышки на нем). Но возникает какая-то лажа с координатами, хотя все мои объекты непосредственные детишки stage, и между ними нет иерархий. Я добавляю curr:БитмапДата на сцену, чтобы посмотреть, что же он в себя поместил методом draw(). В лучшем случае в нем имеется кусочек моего спрайта (если он нарисован ближе к правому краю окна). Но ведь спрайт должен рисоваться в позиции (0,0) объекта curr?! И после всего этого безобразия мышь-мел тоже сбивается с истиного пути и теряет правильные координаты. В чем ошибка, не могу понять. package { public class Main extends MovieClip{ public var desk:Desk=new Desk(); var chalk:Chalk=new Chalk(); var letter:Litera; public function Main() { // constructor code desk.x=50; desk.y=50; stage.addChild(desk).name="desk"; chalk.x=desk.width+desk.x+10; chalk.y=desk.height+desk.y - chalk.height; stage.addChild(chalk).name="chalk"; desk.addEventListener(Chalk.CATCH, desk.drawStart); desk.addEventListener(Chalk.UNCATCH, desk.drawStop); letter=(Litera) (desk.letter); stage.addChild(letter).name="letter"; stage.swapChildren(letter, chalk); var delButton:DelButt=new DelButt(); delButton.x=desk.width+desk.x+10+delButton.width/2; delButton.y=desk.height+desk.y - chalk.height - 30; stage.addChild(delButton); } } } package { public class Litera extends Sprite{ public function Litera() { // constructor code addEventListener(MouseEvent.MOUSE_DOWN, startDragM); addEventListener(MouseEvent.MOUSE_UP, stopDragM); addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, compare); } function startDragM(e:MouseEvent):void{ this.startDrag(); } function stopDragM(e:MouseEvent):void{ this.stopDrag(); } function clean():void{ this.graphics.clear(); } function lockListen():void{ removeEventListener(MouseEvent.MOUSE_DOWN, startDragM); removeEventListener(MouseEvent.MOUSE_UP, stopDragM); removeEventListener(MouseEvent.RIGHT_MOUSE_DOWN, compare); } function compare(e:MouseEvent):void{ var avec:expA=new expA(); //растр, с кот. потом будет сравниваться Litera var copyThis:Litera=new Litera(); copyThis.lockListen(); copyThis.graphics.copyFrom(this.graphics); copyThis.width=avec.width; copyThis.height=avec.height; //var percent:int=0; var curr:BitmapData=new BitmapData(copyThis.width, copyThis.height,true, 0x22331122); curr.draw(copyThis, copyThis.transform.matrix); stage.addChild(new Bitmap(curr)); } } } package { public class Desk extends MovieClip { public function Desk() { // constructor code } public function drawStart(e:Event):void{ stage.addEventListener(MouseEvent.MOUSE_MOVE, drawing); } public function drawStop(e:Event):void{ stage.removeEventListener(MouseEvent.MOUSE_MOVE, drawing); f=true; } //рисование мелом private function drawing(e:MouseEvent):void{ prevX=stage.mouseX; prevY=stage.mouseY; //если мел не выходит за границы доски if (stage.mouseX>this.x && stage.mouseX<(this.x+this.width)&& stage.mouseY>this.y && stage.mouseY<this.y+this.height){ letter.graphics.lineStyle(5,0xFF992233); if (f) letter.graphics.moveTo(prevX, prevY); f=false; letter.graphics.lineTo(stage.mouseX, stage.mouseY); } else{ f=true; } } var prevX, prevY:int; var f:Boolean=true; var letter:Sprite=new Litera(); } } game.zip |
|
|||||
Регистрация: Feb 2013
Сообщений: 11
|
Пробовала без матрицы, пробовала без copyThis работать напрямую с Litera через this. Ничего не работает, как надо. Объект Litera почему-то считает, что его this.x и this.y равны нулю, но при этом свои width и height он определяет правильно.
|
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
А потрейсите, чему равно
trace(this.getBounds(this)); //это в литере trace(copyThis.getBounds(copyThis)); // это там же, после копирования графики. Цитата:
|
|
|||||
Регистрация: Feb 2013
Сообщений: 11
|
Цитата:
Цитата:
И еще вопрос: после того, как я сдвигаю куда-нибудь нарисованную литеру, а потом хочу ее дорисовать, рисующая линия возникает уже не под мелом, а где-то рядом с ним. Как это исправить, не возвращая литеру на прежнее место? |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Ага, я сам тоже проверил. width и height дают фактические размеры контента. Копирование graphics никуда ничего в 0 не переносит, т.е. контент остается в тех же координатах (вычисление bounding box на самом деле далеко не самая простая операция, а вот копирование graphics - простая). Итого - матрицу нужно вручную делать. На самом деле это тривиально:
var copyThis:Litera=new Litera(); copyThis.lockListen(); copyThis.graphics.copyFrom(this.graphics); const bounds : Rectangle = copyThis.getBounds(copyThis); const a : Number = avec.width / bounds.width; const d : Number = avec.height / bounds.height; const trans : Matrix = new Matrix(a, 0, 0, d, -bounds.x, -bounds.y); var curr:BitmapData=new BitmapData(avec.width, avec.height,true, 0x22331122); curr.draw(copyThis, trans); stage.addChild(new Bitmap(curr)); Цитата:
Цитата:
P.S. Примеры не проверял, могут быть опечатки. |
|
|||||
Регистрация: Feb 2013
Сообщений: 11
|
Большое спасибо, it works! Только смещения bounds надо было еще домножить на а и d.
Жаль, конечно, что я пришла к этому путем перебора всех возможных значений и подстановки их во все возможные места, не понимая, что делаю. не комильфо, не по-программерски.
У меня тогда еще вопрос в общем по структуре программы: норм? Правильно ли размещать listener'ы в каждый в своих классах (как у меня) или лучше выносить их в тот класс, кот. будет управлять подключением/выключением? Но ведь тогда получится большая помойка из функций в Main'е. С другой стороны, listener'ов принято делать privat'ами, и если сторонний класс управляет подкл/выкл слушателей другого класса, то придется изменить доступ на public. Где в целом можно посмотреть коды более-менее хороших и "соответствующих всем правилам и концепциям построения и всякое такое" игр, завязанных на программирование, а не на графику? |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Да, с матрицами поправка правильная. Действительно перемещения еще на масштаб нужно было домножить (потому что после масштаба перемещаться нужно меньше).
Цитата:
Слушателей в данном случае можно размещать и в самих классах. Да и не только в этом. До тех пор, пока слушатель реализует неотъемлемое поведение самого объекта (по поводу неотъемлемости формальных критериев нет), он может размещаться в самом объекте. А вот если поведение от объекта "не зависит" или требует взаимодействия со "внешними" объектами, стоит использовать какой-то другой способ (или внешние слушатели, или свои события, или что-то еще). Цитата:
Просто "смотреть" другой код обычно смысла не имеет. Нужно понимать, с какой целью этот код смотрится. Для сопровождения кода (когда он уже давно существует) важны два момента. Первый - навигация по коду. Она определяет, насколько легко найти нужное место (для внесения изменения/правки бага). Второй - собственно легкость внесения изменения (количество переделок, затронутых классов и т.п.). Поэтому обычно имеет смысл не просто смотреть код, а пытаться внести в него какие-то изменения. Можно даже какие-нибудь распространенные библиотеки взять вроде isolib/as3corelib и поиграться с "требованиями". А вдруг мы захотим делать не совсем то, что делает библиотека, а "немного по-другому". Например, поменять какой-то протокол обмена между клиентом/сервером, использовать картинки с прозрачностью вместо векторных и т.п. |
Часовой пояс GMT +4, время: 01:47. |
|
« Предыдущая тема | Следующая тема » |
|
|